The confusion here comes from the same syntax being treated as different in different contexts. In the object initializer, the expression represents a collection initializer.
The spec defines collection initializer as:
7.6.10.3 Collection initializers
A collection initializer consists of a sequence of element initializers, enclosed by { and } tokens and separated by commas. Each element initializer specifies an element to be added to the collection object being initialized, and consists of a list of expressions enclosed by { and } tokens and separated by commas.
Later in the same chapter:
For each specified element in order, the collection initializer invokes an Add method on the target object with the expression list of the element initializer as argument list, applying normal overload resolution for each invocation.
So this is why you get NRE in the first example. Since you don't add a new List<string>
before using the collection initializer, you are attempting to call Add
on a null
object. You will either need to add new List<string>
or do it in the constructor.
An array initializer is different, when you omit new
there the compiler just adds new for you, so this:
string[] values = { "foo", "bar" };
is equivalent to:
string[] values = new [] { "foo", "bar" };
When you use { "foo", "bar" }
outside of the object initializer you get the error because you are trying to assign an array to a list.
Note: In the collection initializer, you might expect the compiler to be smarter and add the new
for you as in the array initializer but it might have other side effects. For example, if you are initializing the list in the constructor, it would overwrite the list. So I guess that's why it's the way it is.