Что это за синтаксис с использованием new, за которым следует список в фигурных скобках? - PullRequest
20 голосов
/ 24 февраля 2012

Я только что видел фрагмент кода, который использует универсальный класс списка, чтобы создать его экземпляр следующим образом:

var foo = new List<string>(){"hello", "goodbye"};

В фигурных скобках после конструктора особенно запутаны.Это мне немного напоминает

var bar = new string[]{"hi","bye"};

, но в прошлом я бы всегда использовал:

var foo = new List<string>(new []{"hello", "goodbye"});

Кто-нибудь получил ссылку, объясняющую синтаксис в первой строке кода?Я даже не знаю, с чего начать гуглить.

Ответы [ 5 ]

36 голосов
/ 24 февраля 2012

Как уже отмечали другие, это инициализатор коллекции.Некоторые другие функции, о которых вы могли не знать, были добавлены в C # 3:

  • Конструктор инициализатора коллекции может опустить скобки, если список аргументов пуст.Так что new List<int> { 10, 20, 30 } в порядке.
  • Массив, инициализированный инициализатором массива, может в некоторых случаях пропустить тип.Например, var myInts = new[] { 10, 20, 30}; означает, что myInts равно int[].
  • Объекты могут быть инициализированы с использованием аналогичного инициализатора объекта синтаксиса.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

, чтобы узнать больше о дизайне этой функции.

30 голосов
/ 24 февраля 2012

вот, пожалуйста.Ключевое слово - «Инициализаторы массива».

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

или, скорее, «Инициализаторы коллекции»

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

16 голосов
/ 24 февраля 2012

Это инициализатор коллекции : 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
}

Этот класс можно инициализировать следующим образом:

var weird = new MyWeirdCollection { 1, "Something", {5, "Something else"} };

Это компилируется во что-то вроде этого:

var temp = new MyWeirdCollection();
temp.Add(1);
temp.Add("Something");
temp.Add(5, "Something else");
var weird = temp;

В своем блоге (ссылка, размещенная Эриком Липпертом в комментариях), Мэдс Торгерсен выражает это кратко:

Список, который вы предоставляете, представляет собой не «список элементов для добавления», а «список наборов аргументов для методов Add». ... [W] мы делаем отдельное разрешение перегрузки для методов Add для каждой записи в списке.

2 голосов
/ 24 февраля 2012

В третьей строке кода, которую вы указали, вы создаете новый строковый массив, а затем передаете этот строковый массив в список. Список затем добавит каждый из этих элементов в список. Это требует дополнительных затрат на выделение массива, его заполнение, а затем отбрасывание.

Для класса существует механизм, определяющий, как использовать инициализаторы коллекции для заполнения себя. (См. Другие ответы) Я никогда не обнаруживал необходимости использовать это для своих собственных классов, но существующие структуры данных, такие как List, Dictionary, часто определяют их, и их полезно использовать.

2 голосов
/ 24 февраля 2012

Это инициализатор коллекции . Вы можете использовать его в коллекциях методом Add.

Пара скобок перед фигурными скобками необязательна.

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

var x = new Dictionary<int,string> {{1, "hello"}, {2, "world"}};

Это позволяет вам избежать более длинной последовательности инициализации:

var x = new Dictionary<int,string>();
x.Add(1, "hello");
x.Add(2, "world");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...