Initialize [NonSerialized] Members

Hi guys,

after long time of abstinence I found an interesting issue to talk about. In our web project we are putting some context informations into the view state, like 1000 other web applications too I think. We developed a special class that holds the values – it called “Context”.

This context class holds some NonSerialized Members like a local cache designed as a hashtable. The problem ist, that after de-serializing the context class the local cache is not initialized although we initialized it within the constructor.

That’s strange – and I have to confess that I really don’t know why it happens.

Here’s a small the example of the context that fails:

/// <summary>
/// Context class
/// </summary>
[Serializable]
public class ContextThatFails
{
    private string serializedValue;
    
    [NonSerialized]
    private Hashtable localCache;
    
    /// <summary>
    /// Initializes a new instance of the <see cref="ContextThatFails"/> class.
    /// </summary>
    public ContextThatFails()
    {
        /*
         * The constructor won't be used when de-serializing the object
         */
        localCache = new Hashtable();
    }
    
    /// <summary>
    /// Gets the local cache.
    /// </summary>
    /// <value>The local cache.</value>
    public Hashtable LocalCache
    {
        get { return localCache; }
    }
    
    /// <summary>
    /// Gets or sets the serialized value.
    /// </summary>
    /// <value>The serialized value.</value>
    public string SerializedValue
    {
        get { return serializedValue; }
        set { serializedValue = value; }
    }
}

When trying to access the hashtable after de-serializing the context the compiler will throw a NullReferenceException.

We solved this problem by verifying the value when accessing the property.
The solution looks like that:

/// <summary>
/// Context class
/// </summary>
[Serializable]
public class ContextThatSucceeds
{
    private string serializedValue;
    
    [NonSerialized]
    private Hashtable localCache;
    
    /// <summary>
    /// Gets the local cache.
    /// </summary>
    /// <value>The local cache.</value>
    public Hashtable LocalCache
    {
        get
        {
            /*
             * We have to initialize the hashtable on access.
             */
            if (localCache == null)
            localCache = new Hashtable();
            return localCache;
        }
    }
    
    /// <summary>
    /// Gets or sets the serialized value.
    /// </summary>
    /// <value>The serialized value.</value>
    public string SerializedValue
    {
        get { return serializedValue; }
        set { serializedValue = value; }
    }
}

The complete source that shows the failing and running example can be downloaded from here:
Initialize [NonSerialized] Members

But my question is still un-answered. Why is the local cache member not initialized after de-serializing although I initialized it within the constructor? If someone has an answer to this I would appreciate if he posts a comment.

So have fun
Cheers

Gerhard