2009-01-05 147 views
6

可以初始化一个这样的数组:集合初始化

int [ ] arr = { 1, 2, 3, 4, 5 }; 

List<T>不允许这样:

List<int> list = { 1, 2, 3, 4, 5 }; 

背后有什么原因呢?

毕竟都允许这样的:

int [ ] arr = new int [ ] { 1, 2, 3, 4, 5 }; 

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

也是为什么它是不可能有LinkedList<T>做到这一点:?

LinkedList<int> ll = new LinkedList<int>() { 1, 2, 3 }; 

更新

谢谢你们。刚刚看到答复。我想选择几个答案,但它并没有让我如此。

为什么LinkedList有一个Add方法,虽然显式实现?这可能会被修复吗?因为这样的问题只会在被忽视时雪球变大,对吧?

回答

14

您的第一个示例是用于初始化整数数组的标准语言语法。左边的值计算为int []。在第二个示例中,您尝试将int []分配给List <int>。赋值运算符不支持这个,因为它们是不同的类型。 A List <int> is not int类型的数组。正如你所说,虽然列表<int>有一个构造函数,它将int []作为参数,并且C#3.0中添加的新语法糖允许使用{}将成员添加到由默认的构造函数。

正如@Patrik所说,这对LinkedList不起作用,因为它没有将Add()方法定义为其接口的一部分(有一个显式的ICollection.Add实现),所以语法糖不会工作。

但是,对于LinkedList有一个简单的解决方法。

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 }; 
1

我从来没有意识到你不能使用LinkedList(T)的集合初始化,但它似乎是合乎逻辑的,因为它没有“Add”方法,而是具有“AddFirst”和“AddLast”。集合初始化使用“添加” - 方法。

1

因为将数组构建到语言中,例如int [],float [],WhateverClassHere []。此语法用于创建数组,而不是初始化列表。

在您的示例中,您正在制作一个整数数组。使用该语法将值添加到列表不应该起作用,因为List不是数组。

+0

您可以像这样实例化复杂类型的数组,它与此无关。问题是为什么创建数组的语法与收集初始化的方式不同。 – 2009-01-05 21:47:32

+0

哦,我没有意识到这一点。 – 2009-01-05 21:51:37

6

这是什么C#3。0语言规格具有对受试者说:

以下是 对象创建表达式的一个例子 包括集合初始化:

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

收集对象到其上 集合初始值设定项应用必须为 为实现 的类型System.Collections.IEnumerable或 发生编译时错误。对于为了每个 指定的元素,所述 集合初始化调用与元件 初始化作为参数列表的 表达式列表在目标对象上的添加 方法,应用针对每个 调用 正常过载的分辨率。因此,集合 对象必须包含适用于每个元素初始值设定项的添加 方法。

当您考虑它时,这是有道理的。编译器确保你正在处理一个实现了Add函数的可枚举类型(通过它进行初始化)。