I have to deal with serializing a bunch of objects. For the sake of simplicity I am using the [Serializable]
attribute together with the binary serializer and binary formatter, excluding non-neccessary fields with [NonSerialized]
for most of the stuff. For the more complex parts I implemented the ISerializable
interface + a deserializing constructor. This works quite well, even when having circular references (in the form of normal object references).
Now I stubled over something that confuses me a bit. When a class B
implementing ISerializable
, and beeing referenced by another class (lets name it Container
) subscribes to an event of that class, the GetObjectData
-Method of B
is called exactly twice when serializing.
[Serializable]
class Container
{
B subObj;
public int X;
public event EventHandler E;
public Container()
{
subObj = new B(this);
}
}
[Serializable]
class B : ISerializable
{
private Container parent;
public B(Container parent) {
this.parent = parent;
parent.E += (sender, e) => { Console.WriteLine(this.parent.X); };
}
protected B(SerializationInfo info, StreamingContext context) { }
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
Console.WriteLine("GetObjectData");
}
}
So this example code writes
GetObjectData
GetObjectData
For a problem with circular effects I'd have rather expected a stack overflow or something :-). Not good nonetheless. A workaround for this example would of course be re-adding the event in the deserializing constructor. But I'd like to get behind what causes this.
One last thing: If one changes the reference in the lambda expression above to the following (referencing the parameter, not the field)...
parent.E += (sender, e) => { Console.WriteLine(parent.X); };
... serialization crashes with an SerializationException
(B+<>c__DisplayClass2 is not marked as Serializable) right after the first time GetObjectData
is executed.
Any hints for why (as well as useful workarounds) appreciated.