If an object implements IDeserializationEventListener, the serialization infrastructure will call that class' OnDeserialization method as soon as the entire graph has been deserialized and all fixups completed. By delaying this callback until as close to the end of the serialization as process, we provide a reasonable opportunity for objects that need to do fixups based on the state of their children. One good example of this is a hashtable, which can make no guarantees about the state of its children until the very end of the graph. By implementing IDeserializationEventListener, the Hashtable can delay running any code on its children (the objects contained within the table) until the entire graph has been deserialized.
//Exerpted from the System.NewCollections implementation of Hashtable. public class Hashtable : ISerializable, IDeserializationEventListener { internal Hashtable(SerializationInfo info, StreamingContext context) { //We can't do anything with the keys and values until the entire graph has been deserialized //and we have a resonable estimate that GetHashCode is not going to fail. For the time being, //we'll just cache this. The graph is not valid until OnDeserialization has been called. m_siInfo = info; } public virtual void OnDeserialization(Object sender, DeserializationEvent dsEvent) { if (m_siInfo==null) { throw new SerializationException(); } loadFactor = (float)m_siInfo.GetValue(LoadFactorName); version = (int)m_siInfo.GetValue(VersionName); comparer = (IComparer)m_siInfo.GetValue(ComparerName); hcp = (IHashCodeProvider)m_siInfo.GetValue(HashCodeProviderName); int hashsize = (int)m_siInfo.GetValue(HashSizeName); loadsize = (int)(loadFactor*hashsize); buckets = new bucket[hashsize]; Object [] serKeys = (Object[])m_siInfo.GetValue(KeysName).ToObject(); Object [] serValues = (Object[])m_siInfo.GetValue(ValuesName).ToObject(); if (serKeys==null || serValues==null) { throw new SerializationException(); } if (serKeys.Length!=serValues.Length) { throw new SerializationException(); } for (int i=0; i<serKeys.Length; i++) { if (serKeys[i]==null) { throw new SerializationException(); } Insert(serKeys[i], serValues[i], true); } m_siInfo=null; } }