这个语法使用new后跟括号内的列表是什么?

max*_*axp 20 c# syntax

我刚刚看到一段代码使用通用列表类以下列方式实例化自己:

var foo = new List<string>(){"hello", "goodbye"};
Run Code Online (Sandbox Code Playgroud)

在构造函数之后的花括号特别令人困惑.它让我想起了一些

var bar = new string[]{"hi","bye"};
Run Code Online (Sandbox Code Playgroud)

但在过去我会一直使用:

var foo = new List<string>(new []{"hello", "goodbye"});
Run Code Online (Sandbox Code Playgroud)

有没有人在第一行代码中找到解释语法的链接?我甚至不知道从哪里开始谷歌搜索它.

Eri*_*ert 36

正如其他人所指出的那样,这是一个集合初始化器.您可能不知道的其他一些功能已添加到C#3:

  • 如果参数列表为空,则集合初始值设定项构造函数可以省略括号.所以new List<int> { 10, 20, 30 }是好的.
  • 在某些情况下,使用数组初始值设定项初始化的数组可能会省略该类型.例如,var myInts = new[] { 10, 20, 30};推断即myIntsint[].
  • 可以使用类似的对象初始化器语法来初始化对象.var c = new Customer() { Name = "Fred" };是相同的var temp = new Customer(); temp.Name = "Fred"; var c = temp;

这些特征的要点是(1)将更多用于需要语句的东西变成只需要表达式的东西; LINQ喜欢表达式,以及(2)启用更丰富的类型推断,特别是对于匿名类型.

最后:关于集合初始化程序所需内容的一些答案和评论中存在一些混淆.要与集合初始化程序一起使用,类型必须(1)实现IEnumerable(以便我们知道它是一个集合)和(2)有一个Add方法(以便我们可以向它添加内容.)

看到

http://blogs.msdn.com/b/madst/archive/2006/10/10/what-is-a-collection_3f00_.aspx

有关该功能设计的其他想法.


min*_*dia 30

干得好.关键字是"Array Initializers".

http://msdn.microsoft.com/en-us/library/aa664573(v=vs.71).aspx

或者说"收集初始化器"

http://msdn.microsoft.com/en-us/library/bb384062.aspx

  • @maxp这不是真的.编译器将集合初始化器转换为对类型的Add方法的调用(有关更多详细信息,请参阅我的答案).一个类型可以在没有Add方法的情况下实现IEnumerable; 集合初始值设定项不能与该类型一起使用.例如,`System.String`实现IEnumerable,但没有`Add`方法. (3认同)

pho*_*oog 16

这是一个集合初始化程序:http://msdn.microsoft.com/en-us/library/bb384062.aspx

如此初始化的类型必须实现IEnumerable并具有Add方法.花括号列表中的项目将传递给add方法; 列表中的不同项可以传递给不同的Add方法.如果存在Add具有多个参数的重载,则将多个参数放在用大括号括起来的逗号分隔列表中.

例如:

class MyWeirdCollection : IEnumerable
{
    public void Add(int i) { /*...*/ }
    public void Add(string s) { /*...*/ }
    public void Add(int i, string s) { /*...*/ }

    //IEnumerable implementation omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)

这个类可以初始化:

var weird = new MyWeirdCollection { 1, "Something", {5, "Something else"} };
Run Code Online (Sandbox Code Playgroud)

这编译成这样的东西:

var temp = new MyWeirdCollection();
temp.Add(1);
temp.Add("Something");
temp.Add(5, "Something else");
var weird = temp;
Run Code Online (Sandbox Code Playgroud)

他的博客文章(Eric Lippert在评论中发表的链接)中,Mads Torgersen简明扼要地表达了这一点:

您提供的列表不是"要添加的元素列表",而是"添加方法的参数集列表".... [W]对列表中的每个条目的Add方法执行单独的重载决策.

  • @maxp:你是对的; 为了与集合初始化程序一起使用,类型必须具有`Add`方法*和*实现`IEnumerable`.原因是:我们发现几乎每个可变集合都有`Add`方法并实现`IEnumerable`.实现"添加"但不是"IEnumerable"的类型往往是算术类,而不是集合类. (2认同)