Чи можу я використовувати ініціалізатор колекції для записів у словнику <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>>?
Shimmy Weitzhandler

після того, як 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

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!" };

Чудова відповідь, я не знав про це! У будь-якому випадку, коли працює ініціалізатор словника? Це лише для підкласів Словник <TKey, TValue> або також буде працювати на ICollection <KeyValuePair <TKey, TValue >>?
Shimmy Weitzhandler

Ініціатори @Shimmy Collection працюють над усім, що реалізує IEnumerable та має Add()методи.
Антон Гоголєв

@Shimmy: словники - це колекції
Джон Сондерс

@JohnSaunders Але ініціалізатор словника приймає два параметри для Add.
Shimmy Weitzhandler

2
@Shimmy: чому це важливо? Справа в тому, що він буде працювати з будь-яким класом, який реалізує IEnumerable<T>і який має Addметод. Якщо Addметод приймає 3 параметри, то вам знадобляться 3 об’єкти в дужках.
Джон Сондерс,

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

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>

або зміна типів ключа або значення пізніше. Якщо ви робите щось подібне на сторінці бритви cshtml, це набагато приємніше подивитися.

Окрім того, що ви менш детальні, ви можете, звичайно, додати до цього класу додаткові методи для того, що б вам не хотілося.


Це, в основному , як ViewDataDictionary працює в MVC - stackoverflow.com/questions/607985 / ...
Simon_Weaver

Я експериментував із типами як "псевдонімами" для словників та набраних масивів, припускаючи, що в типовому світі було б безпечніше використовувати заздалегідь визначені типи. Виявилося, що це не було настільки корисним, коли справа стосувалася дженериків та посилань.
Патрік

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 інших відповідей, які показують, як це зробити. Нам не потрібна 7-а відповідь, що показує те саме.
Серві
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.