[Mono-devel-list] Different behaviour deserializing ISerializable trees Mono <-> .NET

Lluis Sanchez lluis at ximian.com
Mon Aug 25 11:23:46 EDT 2003


Hi!

> Is this a bug or a feature or simply bad usage of serialization? ;-)
> 

It is a bad usage of serialization :)

The order in wich objects are deserialized is not defined. When the
serialization constructor is called, all fields referencing other
objects are guaranteed to be set correctly. However, those objects may
not have been initialized yet. It means that you should not execute any
code that depend on the members of the referred objects.

If you really need to do so, your type should implement the interface
IDeserializationCallback. The interface method OnDeserialization will be
called when the whole object tree has been deserialized. That's where
you should build your hastable.

The different behavior of MS.NET and Mono are due to different
implementations of the serialization engine. Your sample might also fail
in MS.NET under other circumstances.

- Lluis

On dl, 2003-08-25 at 15:29, Jörg Rosenkranz wrote:
> Hi all,
> 
> I have run into a problem serializing/deserializing classes which 
> implement ISerializable.
> 
> I have two classes:
> 1) A data holding class.
> 2) A collection class for objects of class 1
> 
> Both classes implement ISerializable. The class 1 objects are 
> stored in class 2 in a Hashtable internally. I want to restore key 
> to object relation in the deserialization constructor of the 
> collection class.
> 
> My problem is that the collection elements are deserialized *after* the 
> collection class. When I access them in the constructor of class 2
> they are empty.
> 
> You can try the attached sample. It doesn't use Hashtable but shows 
> the different behaviour. Using Mono it prints:
> 
> ========== Serialization ==========
> Serializing TestCollection...
> 0 - Adding member: Value1=member1, Value2=test1 ...
> 1 - Adding member: Value1=member2, Value2=test2 ...
> 2 - Adding member: Value1=member3, Value2=test3 ...
> TestCollection serialized.
> Serializing TestMember: Value1=member3, Value2=test3 ...
> TestMember serialized.
> Serializing TestMember: Value1=member1, Value2=test1 ...
> TestMember serialized.
> Serializing TestMember: Value1=member2, Value2=test2 ...
> TestMember serialized.
> ========== Deserialization ==========
> Deserializing TestCollection...
> 0 - New deserialized member: Value1=, Value2= ...
> 1 - New deserialized member: Value1=, Value2= ...
> 2 - New deserialized member: Value1=, Value2= ...
> Deserialized TestCollection.
> Deserializing TestMember...
> Deserialized TestMember: Value1=member3, Value2=test3
> Deserializing TestMember...
> Deserialized TestMember: Value1=member1, Value2=test1
> Deserializing TestMember...
> Deserialized TestMember: Value1=member2, Value2=test2
> ========== Result ==========
> 0: Value1=member1, Value2=test1
> 1: Value1=member2, Value2=test2
> 2: Value1=member3, Value2=test3
> 
> Running (and compiled too!!) under MS .NET:
> 
> ========== Serialization ==========
> Serializing TestCollection...
> 0 - Adding member: Value1=member1, Value2=test1 ...
> 1 - Adding member: Value1=member2, Value2=test2 ...
> 2 - Adding member: Value1=member3, Value2=test3 ...
> TestCollection serialized.
> Serializing TestMember: Value1=member1, Value2=test1 ...
> TestMember serialized.
> Serializing TestMember: Value1=member2, Value2=test2 ...
> TestMember serialized.
> Serializing TestMember: Value1=member3, Value2=test3 ...
> TestMember serialized.
> ========== Deserialization ==========
> Deserializing TestMember...
> Deserialized TestMember: Value1=member1, Value2=test1
> Deserializing TestMember...
> Deserialized TestMember: Value1=member2, Value2=test2
> Deserializing TestMember...
> Deserialized TestMember: Value1=member3, Value2=test3
> Deserializing TestCollection...
> 0 - New deserialized member: Value1=member1, Value2=test1 ...
> 1 - New deserialized member: Value1=member2, Value2=test2 ...
> 2 - New deserialized member: Value1=member3, Value2=test3 ...
> Deserialized TestCollection.
> ========== Result ==========
> 0: Value1=member1, Value2=test1
> 1: Value1=member2, Value2=test2
> 2: Value1=member3, Value2=test3
> 
> 
> As you can see the result is the same after deserialization
> but not inside the constructor.
> 
> Is this a bug or a feature or simply bad usage of serialization? ;-)
> 
> And no, I can't serialize the Hashtable directly because then it
> would be binary imcompatible between Mono and .NET.
> 
> Thanks in advance for any comments,
> Jörg




More information about the Mono-devel-list mailing list