Новый инициализатор коллекции C#6 - уточнение?

Я прочитал это:

Команда обычно занята внедрением других вариантов инициализаторов. Например, теперь вы можете инициализировать объект Dictionary

Но, глядя на:

var Dic = new Dictionary<string,int>{ {"x",3}, {"y",7} };

В.С.

var Dic = new Dictionary<string,int>{ ["x"]=3, ["y"]=7 };

Я не вижу, где выгода. это выглядит так же. Оба являются не чем иным, как коллекцией имя-значение.
Они поменяли пары фигурных скобок на пары квадратных скобок и несколько запятых

Вопрос:

Какова дополнительная ценность для использования нового синтаксиса? пример реального мира будет высоко ценится.

4 ответа

Решение

Основным преимуществом здесь со словарем является последовательность. Со словарем инициализация не выглядела так же, как использование.

Например, вы можете сделать:

var dict = new Dictionary<int,string>();
dict[3] = "foo";
dict[42] = "bar";

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

var dict = new Dictionary<int,string>
{
    {3, "foo"},
    {42, "bar"}
};

Новый синтаксис инициализации индекса C# 6 делает синтаксис инициализации более совместимым с использованием индекса:

var dict = new Dictionary<int,string>
{ 
    [3] = "foo",
    [42] = "bar"
};

Тем не менее, большее преимущество заключается в том, что этот синтаксис также позволяет инициализировать другие типы. Любой тип с индексатором разрешит инициализацию через этот синтаксис, где старые инициализаторы коллекции работают только с типами, которые реализуют IEnumerable<T> и есть Add метод. Это случилось, чтобы работать с Dictionary<TKey,TValue>, но это не значит, что он работал с любым индексным типом.

Это может быть сомнительная особенность, но новый синтаксис позволяет устанавливать одно и то же несколько раз.

        private static Dictionary<string, string> test1
        = new Dictionary<string, string>() {
            ["a"] = "b",
            ["a"] = "c"
        };

разрешено: здесь ключ "a" имеет значение "c",

Напротив, используя

private static Dictionary<string, string> test2
    = new Dictionary<string, string>() {
        { "a","b" },
        { "a","c" },
    };

создает исключение:

Unbehandelte Ausnahme: System.TypeInitializationException: Der Typeninitialisierer für "ConsoleApplication1.Program" hat eine Ausnahme verursacht. 
---> System.ArgumentException: Ein Element mit dem gleichen Schlüssel wurde bereits hinzugefügt.
   bei System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   bei System.Collections.Generic.Dictionary``2.Insert(TKey key, TValue value, Boolean add)
   bei System.Collections.Generic.Dictionary``2.Add(TKey key, TValue value)
   bei ConsoleApplication1.Program..cctor() in Program.cs:Zeile 19.
   --- Ende der internen Ausnahmestapelüberwachung ---
   bei ConsoleApplication1.Program.Main(String[] args)

Код в первом случае использует синтаксис инициализатора коллекции. Чтобы иметь возможность использовать синтаксис инициализатора коллекции, класс должен:

Инициализаторы коллекции:

  1. Реализовать IEnumerable интерфейс.
  2. Определить доступный Add() метод. (по состоянию на C#6/VS2015 это может быть метод расширения)

Таким образом, класс, определенный так, может использовать синтаксис:

public class CollectionInitializable : IEnumerable
{
    public void Add(int value) { ... }
    public void Add(string key, int value) { ... }
    public IEnumerator GetEnumerator() { ... }
}

var obj = new CollectionInitializable
{
    1,
    { "two", 3 },
};

Не все объекты IEnumerable или имеет метод add и поэтому не может использовать этот синтаксис.


С другой стороны, многие объекты определяют (устанавливаемые) индексаторы. Здесь используется дисионный инициализатор. Может иметь смысл иметь индексаторы, но не обязательно IEnumerable, С инициализатором словаря вам не нужно быть IEnumerableвам не нужно Add() Метод, вам нужен только индексатор.

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

Там нет технической выгоды как таковой; это просто синтаксический сахар (как и многие новые возможности C# 6). В описании возможностей C# PDF, фактически, упоминается только вопрос элегантности:

Инициализаторы объектов и коллекций полезны для декларативной инициализации полей и свойств объектов или для предоставления коллекции начального набора элементов. Инициализация словарей и других объектов с помощью индексаторов менее элегантна. Мы добавляем новый синтаксис для инициализаторов объектов, позволяющий вам устанавливать значения для ключей через любой индексатор, который имеет новый объект

Другие вопросы по тегам