简体   繁体   English

在C#中初始化Generic.List

[英]Initializing a Generic.List in C#

In C#, I can initialize a list using the following syntax. 在C#中,我可以使用以下语法初始化列表。

List<int> intList= new List<int>() { 1, 2, 3 };

I would like to know how that {} syntax works, and if it has a name. 我想知道{}语法是如何工作的,以及它是否有名称。 There is a constructor that takes an IEnumerable , you could call that. 有一个构造函数,它接受一个IEnumerable ,你可以调用它。

List<int> intList= new List<int>(new int[]{ 1, 2, 3 });

That seems more "standard". 这似乎更“标准”。 When I deconstruct the default constructor for the List I only see 当我解构List的默认构造函数时,我只看到了

this._items = Array.Empty;

I would like to be able to do this. 我希望能够做到这一点。

CustomClass abc = new CustomClass() {1, 2, 3};

And be able to use the 1, 2, 3 list. 并且能够使用1, 2, 3列表。 How does this work? 这是如何运作的?

Update 更新

Jon Skeet answered Jon Skeet回答道

It's calling the parameterless constructor, and then calling Add: 它调用无参数构造函数,然后调用Add:

> List<int> tmp = new List<int>();
> tmp.Add(1); tmp.Add(2); tmp.Add(3);
> List<int> intList = tmp;

I understand what is does. 我明白这是做什么的。 I want to know how. 我想知道怎么做。 How does that syntax know to call the Add method? 该语法如何知道调用Add方法?

Update 更新

I know, how cliche to accept a Jon Skeet answer. 我知道,接受Jon Skeet的回答是多么陈词滥调。 But, the example with the strings and ints is awesome. 但是,字符串和整数的例子很棒。 Also a very helpful MSDN page is: 另外一个非常有用的MSDN页面是:

This is called a collection initializer . 这称为集合初始值设定项 It's calling the parameterless constructor, and then calling Add: 它调用无参数构造函数,然后调用Add:

List<int> tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
List<int> intList = tmp;

The requirements for the type are: 该类型的要求是:

  • It implements IEnumerable 它实现了IEnumerable
  • It has overloads of Add which are appropriate for the argument types you supply. 它具有Add重载,适用于您提供的参数类型。 You can supply multiple arguments in braces, in which case the compiler looks for an Add method with multiple parameters. 您可以在大括号中提供多个参数,在这种情况下,编译器会查找具有多个参数的Add方法。

For example: 例如:

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)");
    }
}

You can then use: 然后你可以使用:

DummyCollection foo = new DummyCollection
{
    "Hi",
    "There",
    { 1, 2 }
};

(Of course, normally you'd want your collection to implement IEnumerable properly...) (当然,通常你希望你的集合正确地实现IEnumerable ......)

Read Object and Collection Initializers (C# Programming Guide) . 读取对象和集合初始化器(C#编程指南) Basically you could this with every custom type that is a list (implements IEnumerable). 基本上你可以用每个自定义类型作为列表(实现IEnumerable)。

They're called collection initializers (also see here ), and the way they work is by looking for an Add() method that can do their bidding. 它们被称为集合初始化器 (也见此处 ),它们的工作方式是查找可以进行出价的Add()方法。 It calls Add() for each of the integers you have in your curly braces. 它为花括号中的每个整数调用Add()

The search for the Add() method is pure compiler magic. 搜索Add()方法是纯粹的编译器魔术。 It's hardcoded to find a method of that name. 找到这个名字的方法是硬编码的。

The name you're loooking for is "Collection Initializer". 你正在寻找的名字是“Collection Initializer”。 It works under the hood by looking for a method named Add on the collection type and calling it for every value that you specify. 它通过在集合类型上查找名为Add的方法并为您指定的每个值调用它来工作。

More details: Object and Collection Initializers (C# Programming Guide) 更多细节: 对象和集合初始化器(C#编程指南)

I believe it's a shortcut to the .Add method. 我相信它是.Add方法的捷径。 I've never tried to override it, though, so I don't know if it's possible. 我从来没有尝试过覆盖它,所以我不知道它是否可能。

As far as I'm concerned, the addition of items via object initialization searches a method Add. 就我而言,通过对象初始化添加项目会搜索方法Add。 So, as List<int> will have void Add(int), it will work. 因此,当List <int>将具有void Add(int)时,它将起作用。

To use it in your class, just add 要在课堂上使用它,只需添加即可

class CustomClass { 
   public void Add(int num) {
      // Your code here
   }
}

Your class should implement IEnumerable, as Hallgrim pointed out. Hallgrim指出,你的类应该实现IEnumerable。

It's actually using the .Add method. 它实际上是使用.Add方法。 Meaning it's calling .Add for each item in the brackets inside of the constructor. 这意味着它的呼唤.Add对在构造函数中的括号内为每个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM