C# 集合初始化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/414616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:30:17  来源:igfitidea点击:

Collection initialization

c#.net

提问by Joan Venge

You can initialize an array like this:

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

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

but List<T>doesn't allow this:

List<T>不允许这样做:

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<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?

为什么 LinkedList 通过显式实现有一个 Add 方法?这可能会被修复吗?因为像这样的问题一旦被忽视就会滚雪球成更大的问题,对吗?

采纳答案by tvanfosson

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 notan 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.

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

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.

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

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

但是,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 };

回答by Patrik H?gne

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.

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

回答by Sean James

Because making arrays is built into the language, for example int[], float[], WhateverClassHere[]. This syntax is for making arrays, not initializing lists.

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

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.

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

回答by Jason Hymanson

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

以下是C# 3.0 语言规范对该主题的说明:

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.

以下是包含集合初始值设定项的对象创建表达式的示例:

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

应用集合初始值设定项的集合对象必须是实现 System.Collections.IEnumerable 的类型,否则会发生编译时错误。对于按顺序指定的每个元素,集合初始值设定项调用目标对象上的 Add 方法,并将元素初始值设定项的表达式列表作为参数列表,为每次调用应用正常的重载解析。因此,集合对象必须包含适用于每个元素初始值设定项的 Add 方法。

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).

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

回答by Samuel Hyman

If you'd like to use a collection initializer with LinkedList and don't mind a little inefficiency you can do this:

如果您想在 LinkedList 中使用集合初始值设定项并且不介意效率低下,您可以这样做:

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.

诀窍是使用集合初始值设定项初始化一个数组,然后将其传递到 LinkedList。