Reputation: 330892
You can initialize an array like this:
int [ ] arr = { 1, 2, 3, 4, 5 };
but List<T>
doesn't allow this:
List<int> list = { 1, 2, 3, 4, 5 };
What's the reason behind this?
After all both allow this:
int [ ] arr = new int [ ] { 1, 2, 3, 4, 5 };
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
Also why it's not possible to do this with a LinkedList<T>
?:
LinkedList<int> ll = new LinkedList<int>() { 1, 2, 3 };
Update
Thanks guys. Just saw the replies. I wanted to pick several answers but it didn't let me so.
Why does the LinkedList has an Add method though explicit implementation? Will this likely be fixed? Because problems like this will just snowball into bigger ones when they are overlooked, right?
Upvotes: 6
Views: 18643
Reputation: 33270
15 years on, with C#12 collection expressions, you can use the following syntax, which the compiler will optimize to be as efficient as possible in each case.
int[] array = [1,2,3,4,5];
List<int> list = [1,2,3,4,5];
LinkedList<int> list = new([1,2,3,4,5]);
Old Answer If you'd like to use a collection initializer with LinkedList and don't mind a little inefficiency you can do this:
var linkedList = new LinkedList<int>(new[] { 1, 2, 3, 4 });
The trick is to initialize an array with a collection initializer and then pass that into the LinkedList.
Upvotes: 1
Reputation: 17260
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).
Upvotes: 7
Reputation: 532435
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 };
Upvotes: 18
Reputation: 17141
I never realized you can't use collection initialization with a LinkedList(T), but it seems logical since it has no "Add" method, it instead has "AddFirst" and "AddLast". Collection initialization uses the "Add"-method.
Upvotes: 1
Reputation: 12359
Because making arrays is built into the language, for example int[], float[], WhateverClassHere[]. This syntax is for making arrays, not initializing lists.
In your example, you are making an array of ints. Using that syntax to add values to a list shouldnt work because List isnt an array.
Upvotes: -1