As MSDN states here, it can.
But I’ve spent 2 hours digging mscorlib code, because in some cases the BinaryFormatter called my method marked with OnDeserialized BEFORE deserialization constructor. That is, the order was
OnDeserializing(StreamingContext context)
OnDeserialized(StreamingContext context)
.ctor(SerializationInfo info, StreamingContext context)
While I was expecting it to be
OnDeserializing(StreamingContext context)
.ctor(SerializationInfo info, StreamingContext context)
OnDeserialized(StreamingContext context)
And the final point. When I implemented IDeserializationCallback interface, its method OnDeserialization was called AFTER constructor, as I wanted and expected.
I tried to reproduce this on some simple class structure, but there everything worked fine.
In our project the objects graph being serialized is very complex, so I do not know where to dig. Inspecting the mscorlib code with reflector did not help a lot – the deserialization code is too complicated for me to figure out where the problem comes from.
So, does anybody know what could be causing such problem? We use the assumption that OnDeserialized is called BEFORE the constructor in several other places so I am scared now that it is not very reliable…
Thanks!
Finally, I have the answer to my own question, if anyone would be interested.
Consider the example in the end of this post. There are two classes, instances of which contain references to each other. Under such conditions there is no possibility that deserializing constructors of both instances are passed with constructed objects. So serializer first calls one of constructors passing it an unconstructed instance of second type and then calls constructor of that object, passing it constructed instance of first type. In such a way it helps us to restore objects connections, so it is really the best it can do!
Next,
OnDeserializingandOnDeserializedcallbacks in such cases may be called as I pointed in the question, whileOnDeserializationmethod ofIDeserializationCallbackis always called after the COMPLETE objects graph has been deserialized, exactly as it is stated in its specification.Keeping all the above in mind, I find it the best to use
IDeserializationCallbackinterface to do any post-deserialization processing I need. In that case I am sure that constructors are called for all objects and I can do necessary modifications in a ‘safe’ way.