在C#中初始化Generic.List

Ant*_*y D 46 .net c# generics constructor

在C#中,我可以使用以下语法初始化列表.

List<int> intList= new List<int>() { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)

我想知道该{}语法是如何工作的,如果它有一个名称.有一个构造函数IEnumerable,你可以调用它.

List<int> intList= new List<int>(new int[]{ 1, 2, 3 });
Run Code Online (Sandbox Code Playgroud)

这似乎更"标准".当我解构List的默认构造函数时,我只看到了

this._items = Array.Empty;
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这一点.

CustomClass abc = new CustomClass() {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

并能够使用该1, 2, 3列表.这是如何运作的?

更新

Jon Skeet回答道

它调用无参数构造函数,然后调用Add:

> List<int> tmp = new List<int>();
> tmp.Add(1); tmp.Add(2); tmp.Add(3);
> List<int> intList = tmp;
Run Code Online (Sandbox Code Playgroud)

我明白这是做什么的.我想知道怎么做.该语法如何知道调用Add方法?

更新

我知道,接受Jon Skeet的回答是多么陈词滥调.但是,字符串和整数的例子很棒.另外一个非常有用的MSDN页面是:

Jon*_*eet 65

这称为集合初始值设定项.它调用无参数构造函数,然后调用Add:

List<int> tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
List<int> intList = tmp;
Run Code Online (Sandbox Code Playgroud)

该类型的要求是:

  • 它实现了 IEnumerable
  • 它的重载Add适用于您提供的参数类型.您可以在大括号中提供多个参数,在这种情况下,编译器会查找Add具有多个参数的方法.

例如:

public class DummyCollection : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new InvalidOperationException("Not a real collection!");
    }

    public void Add(string x)
    {
        Console.WriteLine("Called Add(string)");
    }

    public void Add(int x, int y)
    {
        Console.WriteLine("Called Add(int, int)");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

DummyCollection foo = new DummyCollection
{
    "Hi",
    "There",
    { 1, 2 }
};
Run Code Online (Sandbox Code Playgroud)

(当然,通常你希望你的收藏品能够IEnumerable正确实施......)

  • @meandmycode:foreach没有绑定到IEnumerable,因为pre-generics没有其他方法可以在没有装箱的情况下暴露迭代器.使用泛型,我确信它只会*依赖于IEnumerable <T>.(继续) (2认同)
  • 对于需要IEnumerable的集合初始值设定项,它是一个很好的指示,类型真的*是*集合类型,而不是恰好有Add方法(例如DateTime.Add)的另一种类型. (2认同)

Cor*_*nel 7

读取对象和集合初始化器(C#编程指南).基本上你可以用每个自定义类型作为列表(实现IEnumerable).