Новый инициализатор коллекции 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)
Код в первом случае использует синтаксис инициализатора коллекции. Чтобы иметь возможность использовать синтаксис инициализатора коллекции, класс должен:
- Реализовать
IEnumerable
интерфейс. - Определить доступный
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, фактически, упоминается только вопрос элегантности:
Инициализаторы объектов и коллекций полезны для декларативной инициализации полей и свойств объектов или для предоставления коллекции начального набора элементов. Инициализация словарей и других объектов с помощью индексаторов менее элегантна. Мы добавляем новый синтаксис для инициализаторов объектов, позволяющий вам устанавливать значения для ключей через любой индексатор, который имеет новый объект