Поиск…


замечания

Единственное требование для инициализации объекта с использованием этого синтаксического сахара заключается в том, что тип реализует 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() на выходе из объекта.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow