Могу ли я использовать инициализатор коллекции для записей Dictionary <TKey, TValue>?


94

Я хочу использовать инициализатор коллекции для следующего фрагмента кода:

public Dictionary<int, string> GetNames()
{
    Dictionary<int, string> names = new Dictionary<int, string>();
    names.Add(1, "Adam");
    names.Add(2, "Bart");
    names.Add(3, "Charlie");
    return names;
}

Обычно это должно быть примерно так:

return new Dictionary<int, string>
{ 
   1, "Adam",
   2, "Bart"
   ...

Но каков правильный синтаксис для этого?


Отметьте этот пост: marcin-chwedczuk.github.io/…
csharpfolk


не думайте, что это обман, потому что они спрашивали не о синтаксисе объявления сокращенного словаря, а о том, почему сокращение не работает в их (древней) настройке.
NH.

Ответы:


157
var names = new Dictionary<int, string> {
  { 1, "Adam" },
  { 2, "Bart" },
  { 3, "Charlie" }
};

1
Когда работает инициализатор? Это только для Dictionary<TKey, TValue>подклассов или тоже будет работать ICollection<KeyValuePair<TKey, TValue>>?
Шимми Вайцхандлер

после C # 3.0 вы можете использовать varвместо объявляющего типа, или если оставить объявляющий тип, можете опустить new Dictio...- stackoverflow.com/questions/5678216/…
drzaus

1
@drzaus: Использование var - уродливое, уродливое занятие; C # - это строго типизированный язык.
Nyerguds

1
@Nyerguds: что? varбуквально просто экономит нажатия клавиш, он неявно строго типизирован .
drzaus

4
@Nyerguds - я полагаю, вы имеете право на свое мнение, но если вы немедленно инициализируете свои переменные, буквально нет разницы между использованием varи повторением SomeType obj = new SomeType.... А поскольку вы не можете объявить var obj;без немедленной инициализации, я просто не вижу проблемы. На самом деле, я пытаюсь учиться, но не могу понять твою позицию.
drzaus 01

36

Синтаксис немного отличается:

Dictionary<int, string> names = new Dictionary<int, string>()
{
    { 1, "Adam" },
    { 2, "Bart" }
}

Обратите внимание, что вы эффективно добавляете кортежи значений.

В качестве примечания: инициализаторы коллекций содержат аргументы, которые в основном являются аргументами любой функции Add (), которая может пригодиться в отношении типа аргумента времени компиляции. То есть, если у меня есть коллекция:

class FooCollection : IEnumerable
{
    public void Add(int i) ...

    public void Add(string s) ...

    public void Add(double d) ...
}

следующий код совершенно законен:

var foos = new FooCollection() { 1, 2, 3.14, "Hello, world!" };

Отличный ответ, я не знал об этом! В любом случае, когда работает инициализатор словаря? Это только для подклассов Dictionary <TKey, TValue> или также будет работать с ICollection <KeyValuePair <TKey, TValue >>?
Шимми Вайцхандлер

Инициализаторы @Shimmy Collection работают со всем, что реализует IEnumerable и имеет Add()методы.
Антон Гоголев

@Shimmy: словари - это коллекции,
Джон Сондерс,

@JohnSaunders Но инициализатор словаря принимает два параметра для Add.
Шимми Вайцхандлер,

2
@ Шимми: какое это имеет значение? Дело в том, что он будет работать с любым классом, который реализует IEnumerable<T>и имеет Addметод. Если Addметод принимает 3 параметра, то вам понадобится 3 объекта в скобках.
Джон Сондерс,


10

Вопрос отмечен тегами c#-3.0, но для полноты я упомяну новый синтаксис, доступный в C # 6, если вы используете Visual Studio 2015 (или Mono 4.0):

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie"
};

Примечание: старый синтаксис, упомянутый в других ответах, все еще работает, если вам это больше нравится. Опять же, для полноты, вот старый синтаксис:

var dictionary = new Dictionary<int, string>
{
   { 1, "Adam" },
   { 2, "Bart" },
   { 3, "Charlie" }
};

Еще одна интересная вещь, на которую следует обратить внимание, заключается в том, что с любым синтаксисом вы можете оставить последнюю запятую, если хотите, что упрощает копирование / вставку дополнительных строк. Например, следующее прекрасно компилируется:

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie",
};

5

Если вы ищете немного менее подробный синтаксис, вы можете создать подкласс Dictionary<string, object>(или любого другого типа) следующим образом:

public class DebugKeyValueDict : Dictionary<string, object>
{

}

Затем просто инициализируйте вот так

var debugValues = new DebugKeyValueDict
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });

Что эквивалентно

var debugValues = new Dictionary<string, object>
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });

Преимущество заключается в том, что вы получаете все, что вам нужно, например, возможность сказать

is DebugKeyValueDict вместо того is IDictionary<string, object>

или изменить типы ключа или значения позже. Если вы делаете что-то подобное на странице razor cshtml, это намного приятнее.

Помимо того, что вы менее подробны, вы, конечно, можете добавить в этот класс дополнительные методы для всего, что вам нужно.


По сути, ViewDataDictionary работает в MVC - stackoverflow.com/questions/607985/…
Simon_Weaver

Я экспериментировал с типами как «псевдонимами» для словарей и типизированных массивов, предполагая, что в типизированном мире будет безопаснее использовать предопределенные типы. Оказалось, что это не так полезно, когда дело дошло до дженериков и linq.
Патрик

1

В следующем примере кода a Dictionary<TKey, TValue>инициализируется экземплярами типа StudentName.

  Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
  {
      { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
      { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
      { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
  };

из msdn


-3

Да, мы можем использовать инициализатор коллекции в словаре. Если у нас есть такой словарь -

Dictionary<int,string> dict = new Dictionary<int,string>();  
            dict.Add(1,"Mohan");  
            dict.Add(2, "Kishor");  
            dict.Add(3, "Pankaj");  
            dict.Add(4, "Jeetu");

Мы можем инициализировать его следующим образом.

Dictionary<int,string> dict = new Dictionary<int,string>  
            {  

                {1,"Mohan" },  
                {2,"Kishor" },  
                {3,"Pankaj" },  
                {4,"Jeetu" }  

            }; 

4
Уже есть 6 других ответов, показывающих, как это сделать. Нам не нужен седьмой ответ, показывающий то же самое.
Servy
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.