I use a simple class that is serializable. It has a constructor for the deserialization:
protected MyClass(SerializationInfo info, StreamingContext context)
The order of the calls depend on wether the object is the root of the serialized tree or some member of an object, which is also serialized in the same object graph. I get the following output with the extended example provided by Marc Gravell:
SerRoot.ctor
SerMember.ctor
> serializing
SerRoot.OnSerializingMethod
GetObjectData
SerMember.OnSerializingMethod
SerMember.GetObjectData
SerRoot.OnSerializedMethod
SerMember.OnSerializedMethod
< serializing
> deserializing
SerRoot.OnDeserializingMethod
SerMember.OnDeserializingMethod
SerMember.OnDeserializedMethod
SerMember.ctor(info, context)
SerRoot.ctor(info, context)
SerRoot.OnDeserializedMethod
< deserializing
Notice that in deserialization SerMember.ctor is called after SerMember.OnDeserializedMethod! This is the code:
static void Main(string[] args)
{
using (var ms = new MemoryStream())
{
var orig = new SerRoot();
var ser = new BinaryFormatter();
System.Console.WriteLine("> serializing");
ser.Serialize(ms, orig);
System.Console.WriteLine("< serializing");
ms.Position = 0;
System.Console.WriteLine("> deserializing");
ser.Deserialize(ms);
System.Console.WriteLine("< deserializing");
}
}
[Serializable]
class SerRoot : ISerializable
{
public SerMember m;
public SerRoot()
{
System.Console.WriteLine("SerRoot.ctor");
m = new SerMember();
}
protected SerRoot(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("SerRoot.ctor(info, context)");
m = info.GetValue("m", typeof(SerMember)) as SerMember;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("GetObjectData");
info.AddValue("m", m);
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnDeserializingMethod"); }
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnDeserializedMethod"); }
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnSerializingMethod"); }
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnSerializedMethod"); }
}
[Serializable]
class SerMember : ISerializable
{
string text;
public SerMember()
{
System.Console.WriteLine("SerMember.ctor");
text = "test";
}
protected SerMember(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("SerMember.ctor(info, context)");
text = info.GetString("text");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("SerMember.GetObjectData");
info.AddValue("text", text);
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnDeserializingMethod"); }
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnDeserializedMethod"); }
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnSerializingMethod"); }
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnSerializedMethod"); }
}