Search code examples
c#dictionarysyntaxinitializer

C# dictionary initializer compilation inconsistency


The following code compiles, but fails with a NullReferenceException:

class Test
{
    public Dictionary<string, string> Dictionary { get; set; }
}

static void Main(string[] args)
{
    var x = new Test
    {
        Dictionary =   // fails
        {
            { "key", "value" }, { "key2", "value2" }
        }
    };
}

If you replace the line marked 'fails' with the following, it works (as expected):

Dictionary = new Dictionary<string, string> 

Is there any purpose to the failing syntax--can it be used successfully in some other case? Or is this an oversight in the compiler?


Solution

  • No, it's not a mistake... it's a flaw in your understanding of initialization syntax :)

    The idea of the

    Dictionary = { ... }
    

    is for cases where the caller has read access to a collection property, but not write access. In other words, situations like this:

    class Test
    {
        private readonly Dictionary<string, string> dictionary 
            = new Dictionary<string, string>();
        public Dictionary<string, string> Dictionary { get { return dictionary; } }
    }
    

    Basically it ends up being calls to Add, but without creating a new collection first. So this code:

    Test test = new Test { Dictionary = { { "a", "b"}, {"c", "d" } };
    

    is equivalent to:

    Test tmp = new Test();
    Dictionary<string, string> tmpDictionary = tmp.Dictionary;
    tmpDictionary.Add("a", "b");
    tmpDictionary.Add("c", "d");
    Test test = tmp;
    

    A good example of where this is useful is with the Controls collection for a UI. You can do this:

    Form form = new Form
    {
        Controls = 
        {
            new Button { Text = "Hi" }, 
            new TextBox { Text = "There" } 
        }
    };
    

    but you couldn't actually set the Controls property, because it's read-only.