C# Language
Инициализаторы коллекции
Поиск…
замечания
Единственное требование для инициализации объекта с использованием этого синтаксического сахара заключается в том, что тип реализует System.Collections.IEnumerable
и метод Add
. Хотя мы называем это инициализатором коллекции, объект не должен быть коллекцией.
Инициализаторы коллекции
Инициализировать тип коллекции со значениями:
var stringList = new List<string>
{
"foo",
"bar",
};
Инициализаторы коллекции - это синтаксический сахар для вызовов Add()
. Вышеуказанный код эквивалентен:
var temp = new List<string>();
temp.Add("foo");
temp.Add("bar");
var stringList = temp;
Обратите внимание, что инициализация выполняется атомарно с использованием временной переменной, чтобы избежать условий гонки.
Для типов, которые предлагают несколько параметров в методе Add()
, заключают аргументы, разделенные запятыми, в фигурные скобки:
var numberDictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
};
Это эквивалентно:
var temp = new Dictionary<int, string>();
temp.Add(1, "One");
temp.Add(2, "Two");
var numberDictionarynumberDictionary = temp;
Инициализаторы индекса C # 6
Начиная с C # 6, коллекции с индексаторами могут быть инициализированы путем указания индекса для назначения в квадратных скобках, за которым следует знак равенства, а затем значение для назначения.
Инициализация словаря
Пример этого синтаксиса с использованием словаря:
var dict = new Dictionary<string, int>
{
["key1"] = 1,
["key2"] = 50
};
Это эквивалентно:
var dict = new Dictionary<string, int>();
dict["key1"] = 1;
dict["key2"] = 50
Синтаксис инициализатора коллекции, чтобы сделать это до C # 6:
var dict = new Dictionary<string, int>
{
{ "key1", 1 },
{ "key2", 50 }
};
Что соответствовало бы:
var dict = new Dictionary<string, int>();
dict.Add("key1", 1);
dict.Add("key2", 50);
Таким образом, существует значительная разница в функциональности, поскольку новый синтаксис использует индексатор инициализированного объекта для назначения значений вместо использования метода Add()
. Это означает, что новый синтаксис требует только общедоступного индексатора и работает для любого объекта, который имеет один.
public class IndexableClass
{
public int this[int index]
{
set
{
Console.WriteLine("{0} was assigned to index {1}", value, index);
}
}
}
var foo = new IndexableClass
{
[0] = 10,
[1] = 20
}
Это приведет к выводу:
10 was assigned to index 0
20 was assigned to index 1
Инициализаторы коллекции в пользовательских классах
Чтобы создать инициализаторы коллекции поддержки класса, он должен реализовать интерфейс IEnumerable
и иметь хотя бы один метод Add
. Начиная с C # 6, любая коллекция, реализующая IEnumerable
может быть дополнена пользовательскими методами Add
с использованием методов расширения.
class Program
{
static void Main()
{
var col = new MyCollection {
"foo",
{ "bar", 3 },
"baz",
123.45d,
};
}
}
class MyCollection : IEnumerable
{
private IList list = new ArrayList();
public void Add(string item)
{
list.Add(item)
}
public void Add(string item, int count)
{
for(int i=0;i< count;i++) {
list.Add(item);
}
}
public IEnumerator GetEnumerator()
{
return list.GetEnumerator();
}
}
static class MyCollectionExtensions
{
public static void Add(this MyCollection @this, double value) =>
@this.Add(value.ToString());
}
Инициализаторы коллекции с массивами параметров
Вы можете смешивать обычные параметры и массивы параметров:
public class LotteryTicket : IEnumerable{
public int[] LuckyNumbers;
public string UserName;
public void Add(string userName, params int[] luckyNumbers){
UserName = userName;
Lottery = luckyNumbers;
}
}
Этот синтаксис теперь возможен:
var Tickets = new List<LotteryTicket>{
{"Mr Cool" , 35663, 35732, 12312, 75685},
{"Bruce" , 26874, 66677, 24546, 36483, 46768, 24632, 24527},
{"John Cena", 25446, 83356, 65536, 23783, 24567, 89337}
}
Использование инициализатора коллекции внутри инициализатора объекта
public class Tag
{
public IList<string> Synonyms { get; set; }
}
Synonyms
- это свойство типа коллекции. Когда объект Tag
создается с использованием синтаксиса инициализатора объекта, Synonyms
также могут быть инициализированы синтаксисом инициализатора коллекции:
Tag t = new Tag
{
Synonyms = new List<string> {"c#", "c-sharp"}
};
Свойство коллекции может быть только для чтения и по-прежнему поддерживать синтаксис инициализатора коллекции. Рассмотрим этот модифицированный пример (свойство Synonyms
теперь имеет частный сеттер):
public class Tag
{
public Tag()
{
Synonyms = new List<string>();
}
public IList<string> Synonyms { get; private set; }
}
Новый объект Tag
может быть создан следующим образом:
Tag t = new Tag
{
Synonyms = {"c#", "c-sharp"}
};
Это работает, потому что инициализаторы коллекции являются просто синтаксическим сахаром над вызовами Add()
. Здесь нет нового списка, компилятор просто генерирует вызовы Add()
на выходе из объекта.