Serialization of a class with events
Asked Answered
S

4

22

I have a Class like this:

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;
}

I also have another Class (StepPulseblaster) which is not serializable and adds an Event Handler

valDouble.Changed += new ChangedEventHandler(sc_PropertyChanged);

When i try to serialize the valueDouble Class, there will be an error:

The Type StepPulseblaster is not marked as serializable

When i comment the line

valDouble.Changed += ...

there will be no error any more.

How can i serialize a class which has some events connected?

Samothrace answered 30/5, 2012 at 13:8 Comment(4)
Do you want the events to still be there when you deserialize it, or do you want to serialize the data without the events?Lindholm
I use the Event to update a GUI, so i need the event after I deserialize it. I have about 1000 duplicates of this Class so I do not really want to delete the event before serialization and create it again.Samothrace
Okay, next question: why are you serializing the object? Are you storing it somewhere and reloading it later, or are you making it accessible to a different context (e.g. a different AppDomain or a different process)? You won't be able to serialize the reference to your GUI, but depending on what you need, there may be easy ways to accomplish what you're after.Lindholm
I want to save it to disk and be able to restore it later.Samothrace
P
33

You should do:

[field: NonSerialized]
public event ChangedEventHandler Changed;

As described in the MSDN:

To apply the NonSerializedAttribute class to an event, set the attribute location to field.

Pinkie answered 27/5, 2015 at 13:23 Comment(2)
Thats interesting, never knew you could do that.Wagoner
That link to the docs does not seem to go anywhere useful. Has there been some link rot?Hyunhz
O
13

The NonSerialized attribute is only available for fields, so to use it you have to adjust your code to use fields.

Try creating your event like this:

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

Then in the value property use the field, not the property:

public double value
{
    get { return _value; }
    set 
    {
        _value = value;
        if (_changed != null)
        {
            _changed(this, EventArgs.Empty);
        }
    }
}
private double _value = 0;
Obedient answered 14/5, 2013 at 14:24 Comment(0)
S
1

Use the [NonSerialized] attribute to avoid serialization of the event.

Spectroscope answered 30/5, 2012 at 13:15 Comment(1)
In VS2010, applying [NonSerialized] to an event gives an error: "Error 2 Attribute 'NonSerialized' is not valid on this declaration type. It is only valid on 'field' declarations."Greenbelt
D
1

Either mark StepPulseBlaster as serializable or use the XmlIgnore attribute to prevent Changed from being serialized.

Defaulter answered 30/5, 2012 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.