集合初始化

时间:2009-01-05 21:39:06

标签: c# .net

您可以像这样初始化数组:

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方法,但显式实现?这可能会被修复吗?因为这样的问题在被忽视时会变成更大的问题,对吗?

5 个答案:

答案 0 :(得分:15)

您的第一个示例是初始化整数数组的标准语言语法。左侧值的计算结果为int []。在第二个示例中,您尝试将int []分配给List&lt; int&gt;。赋值运算符不支持它,因为它们是不同的类型。列表&lt; int&gt;是不是类型为int的数组。如你所说,有一个List&lt; int&gt;的构造函数。确实以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 :(得分:7)

以下是 C#3.0语言规范对此主题的评论:

  

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

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

a。的集合对象   必须应用集合初始化程序   是一种实现的类型   System.Collections.IEnumerable或a   发生编译时错误。对于每一个   按顺序指定元素   集合初始化程序调用Add   用目标对象的方法   元素的表达式列表   初始化器作为参数列表,应用   每个的正常重载分辨率   调用。因此,收集   对象必须包含适用的Add   每个元素初始化程序的方法。

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

如果您想将集合初始化器与LinkedList一起使用,并且不介意效率低下,则可以执行以下操作:

var linkedList = new LinkedList<int>(new[] { 1, 2, 3, 4 });

技巧是使用集合初始化程序初始化数组,然后将其传递给LinkedList。