Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hashtable.OnDeserialization

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);
}
like image 749
jameswelle Avatar asked Nov 10 '08 23:11

jameswelle


2 Answers

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.

like image 107
Gaspar Nagy Avatar answered Nov 12 '22 11:11

Gaspar Nagy


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"]);

}
like image 3
Brian Adams Avatar answered Nov 12 '22 11:11

Brian Adams