Collection initialization

Your first sample is the standard language syntax for initializing an array of integers. The left-hand value evaluates to int[]. In the second sample you are attempting to assign an int[] to a List<int>. The assignment operator doesn't support this as they are different types. A List<int> is not an array of type int. As you say, though, there is a constructor for List<int> that does take an int[] as an argument and the new syntactic sugar added in C# 3.0 allows you the convenience of using { } to add members to the collection defined by the default constructor.

As @Patrik says, this won't work for LinkedList because it doesn't define the Add() method as part of its interface (there is an explicit implementation of ICollection.Add) so the syntactic sugar won't work.

There is an easy work-around for LinkedList, however.

public class LinkedListWithInit<T> : LinkedList<T>
{
    public void Add( T item )
    {
        ((ICollection<T>)this).Add(item);
    }
}

LinkedList<int> list = new LinkedListWithInit<int> { 1, 2, 3, 4, 5 };

Here is what the C# 3.0 Language Spec has to say on the subject:

The following is an example of an object creation expression that includes a collection initializer:

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

The collection object to which a collection initializer is applied must be of a type that implements System.Collections.IEnumerable or a compile-time error occurs. 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. Thus, the collection object must contain an applicable Add method for each element initializer.

That makes sense when you think about it. The compiler makes sure you are working on an enumerable type that implements an Add function (through which it does the initialization).

Tags:

C#

.Net