Инициализация Generic.List в C # - PullRequest
46 голосов
/ 15 апреля 2009

В C # я могу инициализировать список, используя следующий синтаксис.

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

Я хотел бы знать, как работает этот синтаксис {} и есть ли у него имя. Есть конструктор, который принимает IEnumerable, это можно назвать.

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

Это кажется более "стандартным". Когда я деконструирую конструктор по умолчанию для списка, я вижу только

this._items = Array.Empty;

Я бы хотел это сделать.

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

И сможете использовать список 1, 2, 3. Как это работает?

Обновление

Джон Скит ответил

Это вызывает без параметров конструктор, а затем вызвать Add:

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

Я понимаю, что делает. Я хочу знать как. Как этот синтаксис узнает, как вызвать метод Add?

Обновление

Я знаю, как клише, чтобы принять ответ Джона Скита. Но пример со строками и целыми числами потрясающий. Также очень полезная страница MSDN:

Ответы [ 7 ]

65 голосов
/ 15 апреля 2009

Это называется инициализатором коллекции . Он вызывает конструктор без параметров, а затем вызывает Add:

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

Требования к типу:

  • Он реализует 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)");
    }
}

Затем вы можете использовать:

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

(Конечно, обычно вы хотите, чтобы ваша коллекция правильно реализовала IEnumerable ...)

7 голосов
/ 15 апреля 2009

Чтение Инициализаторы объектов и коллекций (Руководство по программированию в C #) . По сути, вы можете сделать это с каждым пользовательским типом, являющимся списком (реализует IEnumerable).

4 голосов
/ 15 апреля 2009

Они называются инициализаторами коллекции (см. Также здесь ), и способ их работы заключается в поиске Add() метода, который может выполнять свои ставки. Он вызывает Add() для каждого целого числа, которое есть в ваших фигурных скобках.

Поиск метода Add() - чистая магия компилятора. Трудно найти метод с таким именем.

2 голосов
/ 15 апреля 2009

Имя, которое вы ищите - «Инициализатор коллекции». Он работает под капотом, ища метод с именем Add для типа коллекции и вызывая его для каждого указанного вами значения.

Подробнее: Инициализаторы объектов и коллекций (Руководство по программированию в C #)

1 голос
/ 15 апреля 2009

Я считаю, что это ярлык для метода .Add. Я никогда не пытался переопределить это, поэтому я не знаю, возможно ли это.

0 голосов
/ 15 апреля 2009

На самом деле используется метод .Add. Это означает, что он вызывает .Add для каждого элемента в скобках внутри конструктора.

0 голосов
/ 15 апреля 2009

Насколько я понимаю, добавление элементов посредством инициализации объекта ищет метод Add. Так как List будет иметь void Add (int), он будет работать.

Чтобы использовать его в своем классе, просто добавьте

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

Ваш класс должен реализовывать IEnumerable, как указывал Халлгрим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...