Collection initialization is not construction

The ability to initialize collections is a great feature of C# 3.0, but it may not work exactly as you expected.

Consider the following class:

internal class MyListContainer
{
   internal List<object> MyObjects { get; set; }
}

Now, imagine a call site that does the following:

MyListContainer mlc = new MyListContainer
{
    MyObjects = { DateTime.Now, new Object() }
};

Does the code work?

No, it doesn’t. Even though MyObjects gets initialized with the two values, the list was never constructed. You get a runtime NullReferenceException, and it may be a confusing one – it’s very hard to see what’s null in the debugger. Remember: The collection initialization only calls the Add method on the collection for each of the items passed.

You can fix this two ways: Either construct the list in the class itself or construct it at the call site. The first option requires the addition of a simple constructor:

public MyListContainer()
{
    MyObjects = new List<object>();
}

The second option adds the new operator onto the initialization syntax:

MyListContainer mlc = new MyListContainer
{
    MyObjects = new List<object> { DateTime.Now, new Object() }
};

Either will work. Personally, I would prefer the constructor approach to hide the ugliness from the initialization site. Of course, if your classes only rarely need the collection and very many instances are created, the automatic construction for every object may be excessive. The solution may be using on-demand hidden construction. Again, the initializer only calls “Add” on the collection class. So if your class was written as:

internal class MyListContainer
{
    private List<object> myObjects;
    internal List<object> MyObjects 
    {
        get 
        {
            if (myObjects == null) { myObjects = new List<object>(); }
            return myObjects;
        }
    }
}

Then the code would work even if the call site didn’t explicitly initialize the collection. And note that a setter isn’t even necessary even though the initializer syntax strongly looks like it!

September 16, 2009 · Jouni Heikniemi · No Comments
Tags:  · Posted in: .NET

Leave a Reply