Сериализация класса с событиями

У меня есть класс вроде этого:

public delegate void ChangedEventHandler(object sender, EventArgs e);
[Serializable]
public class valueDouble
{
    public event ChangedEventHandler Changed;
    public double value
    {
        get { return _value; }
        set 
        {
            _value = value;
            if (Changed != null)
            {
                Changed(this, EventArgs.Empty);
            }
        }
    }
    private double _value = 0;
}

У меня также есть еще один класс (StepPulseblaster), который не является сериализуемым и добавляет обработчик событий

valDouble.Changed += new ChangedEventHandler(sc_PropertyChanged);

Когда я пытаюсь выполнить сериализацию класса ValueDouble, возникнет ошибка:

The Type StepPulseblaster is not marked as serializable

Когда я прокомментирую строку

valDouble.Changed += ...

больше не будет ошибок.

Как я могу сериализовать класс, связанный с некоторыми событиями?

Ответы

Ответ 1

Вам следует:

[field: NonSerialized]
public event ChangedEventHandler Changed;

Как описано в документах:

В случае событий вы также должны добавить квалификатор атрибута поля при применении атрибута NonSerialized, чтобы атрибут был применен к базовому делегату, а не самому событию:

Ответ 2

Атрибут NonSerialized доступен только для полей, поэтому для его использования вы должны настроить свой код для использования полей.

Попробуйте создать свое событие следующим образом:

[NonSerialized]
private ChangedEventHandler _changed;
public event ChangedEventHandler Changed
{
    add { _changed += value; }
    remove { _changed -= value; }
}

Затем в свойстве value используйте поле, а не свойство:

public double value
{
    get { return _value; }
    set 
    {
        _value = value;
        if (_changed != null)
        {
            _changed(this, EventArgs.Empty);
        }
    }
}
private double _value = 0;

Ответ 3

Используйте атрибут [NonSerialized], чтобы избежать сериализации события.

Ответ 4

Отметьте StepPulseBlaster как сериализуемый или используйте атрибут XmlIgnore, чтобы предотвратить изменение сериализации.