21 November 2010

C# Object Initialization Wonders

Since I am coding a lot in JavaScript recently I tend to use C# Object Initialization more often than before. Last evening I had an astonishing experience …

I had a class Foo

public class Foo
{
    public List<string> Data { get; set; }
}

and wrote this object initializer:

var bar = new Foo {Data = {"a", "b"}};

The first wonder was that this code actually compiles. Fine, nearly as compact as JavaScript. But at runtime I had a mysterious error. When I finally inspected the Data property with Debug.WriteLine(string.Join(", ", bar.Data)); it contains 1, 2, a, b and not the expected a, b. So the former assignment to Data was not setting the property but somehow adding to the existing content. Looking into the Foo constructor proved this.

public Foo()
{
    Data = new List<string>{"1", "2"};
}

The compiler interpreted the assignment to the Data property as a collection initializer and was just calling Add() for “a” and “b” on the existing collection. To overwrite the existing collection I had to specify a new type:

var bar = new Foo {Data = new List<string>{"a", "b"}};

I’m not really sure if this is a bug or a feature …