С# 6 новый Инициализатор коллекции - Уточнение?
Я читал, что:
Команда, как правило, была занята реализацией других вариантов Инициализаторы. Например, теперь вы можете инициализировать объект Dictionary
Но глядя на:
var Dic = new Dictionary<string,int>{ {"x",3}, {"y",7} };
VS
var Dic = new Dictionary<string,int>{ ["x"]=3, ["y"]=7 };
Я не вижу, где это преимущество. это выглядит так же. Оба являются не чем иным, как коллекцией имен.
Они поменяли пары фигурных скобок для пар квадратных скобок и некоторых запятых
Вопрос:
Какова добавленная стоимость использования нового синтаксиса? пример с реальным миром был бы очень оценен.
Ответы
Ответ 1
Основным преимуществом здесь со словарем является согласованность. С помощью словаря инициализация выглядела не так, как использование.
Например, вы можете сделать:
var dict = new Dictionary<int,string>();
dict[3] = "foo";
dict[42] = "bar";
Но используя синтаксис инициализации, вам нужно было использовать фигурные скобки:
var dict = new Dictionary<int,string>
{
{3, "foo"},
{42, "bar"}
};
Новый синтаксис инициализации индекса С# 6 делает синтаксис инициализации более согласованным с использованием индекса:
var dict = new Dictionary<int,string>
{
[3] = "foo",
[42] = "bar"
};
Однако большее преимущество заключается в том, что этот синтаксис также дает возможность инициализировать другие типы. Любой тип с индексом позволяет инициализировать этот синтаксис, когда старые инициализаторы коллекции работают только с типами, которые реализуют IEnumerable<T>
и имеют метод Add
. Это случилось с Dictionary<TKey,TValue>
, но это не значит, что он работал с любым типом, основанным на индексе.
Ответ 2
Код в первом случае использует синтаксис инициализатора коллекции. Чтобы иметь возможность использовать синтаксис инициализатора коллекции, класс должен:
Инициализаторы коллекции:
- Внедрить интерфейс
IEnumerable
.
- Определите доступный метод
Add()
. (с С# 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
или имеют метод добавления и поэтому не могут использовать этот синтаксис.
С другой стороны, многие объекты определяют (устанавливаемые) индексы. Здесь используется инициализатор dicionary. Возможно, имеет смысл иметь индексаторы, но необязательно быть IEnumerable
. С помощью инициализатора слова вам не нужно быть IEnumerable
, вам не нужен метод Add()
, вам нужен только индекс.
Возможность полностью инициализировать объект в одном выражении обычно полезна (и в некоторых контекстах - требование). Синтаксис инициализатора словаря упрощает выполнение этого без крутых требований использования инициализаторов коллекции.
Ответ 3
Это может быть сомнительная функция, но новый синтаксис позволяет вам устанавливать одинаковые несколько раз.
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)
Ответ 4
Там нет технической выгоды как таковой; это просто синтаксический сахар (как и многие новые функции С# 6). описания функций С# PDF, на самом деле, упоминает только вопрос элегантности:
Инициализаторы объектов и коллекций полезны для декларативно инициализации полей и свойств объектов или предоставления коллекции исходного набора элементов. Инициализация словарей и других объектов с помощью индексаторов менее изящна. Мы добавляем новый синтаксис к инициализаторам объектов, которые позволяют вам устанавливать значения для ключей через любого индексатора, что новый объект имеет