Question

I have a class that maintans a reference to a Hashtable and serializes/deserializes that Hashtable. After the call to SerializationInfo.GetValue, the Hashtable is not fully deserialized because the deserialization happens during the IDeserialization calback.

Hashtable hashtable = (Hashtable) info.GetValue("hash", typeof(Hashtable));

I also implemented the IDeserialization callback in the parent class, but there too the Hashtable is not fully deserialized yet. I expected it to be if the deserialization is happening from the inside out.

My question is, is it safe to explicitely call Hashtable.OnDeserialization from the OnDeserialization method of my parent class, so that I can enumerate it at that point?

public virtual void OnDeserialization(object sender)
{
    hashtable.OnDeserialization(sender);
}
Was it helpful?

Solution

This is really an interesting issue. After checking the serialization code with Reflector, I think that there is no generally good soluiton if a referred class uses IDeserializationCallback.

Probably you have seen, that there are two other ways as well to run some code during deserialization, the [OnDeserializing] and the [OnDeserialized] attributes. Unfortuanately both runs before the IDeserializationCallback.OnDeserialization(). This is the run order of the methods if you have class1 that refers to a class2:

Class1: [OnDeserializing]
Class2: [OnDeserializing]
Class2: [OnDeserialized]
Class1: [OnDeserialized]
Class1: IDeserializationCallback.OnDeserialization
Class2: IDeserializationCallback.OnDeserialization

As you can see, the [OnDeserializing] and the [OnDeserialized] attributes work consistent, but the IDeserializationCallback methods not really... :(

I have also checked the OnDeserialization implementation of Hashtable and Dictionary, and both seems to be safe for calling the OnDeserialization more than once (only the first call will perform the necessary operation, the subsequent calls will do nothing).

So finally you should call the OnDeserialization() of the Hashtable, as Sean and Brian suggested.

OTHER TIPS

I suspect you have already googled, but I happened to across this pattern yesterday.

public BoringClass(SerializationInfo info, StreamingContext context)
{
    Hashtable hashtable = (Hashtable) info.GetValue("hash", typeof(Hashtable));
    hashtable.OnDeserialization(this);

    Console.WriteLine("Value is: " + hashtable["testItem"]);

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top