Posso usare un inizializzatore di raccolta per le voci del dizionario <TKey, TValue>?


94

Voglio usare un inizializzatore di raccolta per il prossimo bit di codice:

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

Quindi in genere dovrebbe essere qualcosa del tipo:

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

Ma qual è la sintassi corretta per questo?


Controlla questo post: marcin-chwedczuk.github.io/…
csharpfolk


non pensare che sia uno stupido, perché stavano chiedendo, non per la sintassi della dichiarazione del dizionario abbreviato, ma per il motivo per cui la stenografia non funzionava nella loro (antica) configurazione.
NH.

Risposte:


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

1
Quando funziona l'inizializzatore? È solo per le Dictionary<TKey, TValue>sottoclassi o funzionerà anche ICollection<KeyValuePair<TKey, TValue>>?
Shimmy Weitzhandler

dopo C # 3.0 è possibile utilizzare varal posto del tipo di dichiarazione, o se lasciare il tipo di dichiarazione può omettere il new Dictio...- stackoverflow.com/questions/5678216/...
drzaus

1
@drzaus: Usare var è comunque una brutta pratica; C # è un linguaggio fortemente tipizzato.
Nyerguds

1
@Nyerguds: cosa? varletteralmente ti salva solo le battiture, è implicitamente fortemente digitato .
drzaus

4
@Nyerguds - hai diritto alla tua opinione, immagino, ma se stai inizializzando immediatamente le tue variabili non c'è letteralmente alcuna differenza tra usare vare ripetere te stesso con SomeType obj = new SomeType.... E poiché non puoi dichiarare var obj;senza inizializzare immediatamente, semplicemente non vedo il problema. Davvero, sto cercando di imparare, ma non riesco a capire la tua posizione.
drzaus

36

La sintassi è leggermente diversa:

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

Nota che stai effettivamente aggiungendo tuple di valori.

Come nota a margine: gli inizializzatori di raccolta contengono argomenti che sono fondamentalmente argomenti per qualsiasi funzione Add () che risulta utile rispetto al tipo di argomento in fase di compilazione. Cioè, se ho una collezione:

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

    public void Add(string s) ...

    public void Add(double d) ...
}

il seguente codice è perfettamente legale:

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

Ottima risposta, non lo sapevo! Ad ogni modo, quando funziona l'inizializzatore del dizionario? È solo per le sottoclassi Dictionary <TKey, TValue> o funziona anche su ICollection <KeyValuePair <TKey, TValue >>?
Shimmy Weitzhandler

Gli inizializzatori di @Shimmy Collection funzionano su tutto ciò che implementa IEnumerable e ha Add()metodi.
Anton Gogolev

@ Shimmy: i dizionari sono raccolte
John Saunders,

@ JohnSaunders Ma un inizializzatore di dizionario accetta due parametri per Add.
Shimmy Weitzhandler

2
@ Shimmy: perché è importante? Il punto è che funzionerà con qualsiasi classe che implementa IEnumerable<T>e che ha un Addmetodo. Se il Addmetodo accetta 3 parametri, avrai bisogno di 3 oggetti tra parentesi.
John Saunders

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

10

La domanda è contrassegnata c#-3.0, ma per completezza menzionerò la nuova sintassi disponibile con C # 6 nel caso in cui si utilizzi Visual Studio 2015 (o Mono 4.0):

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

Nota: la vecchia sintassi menzionata in altre risposte funziona comunque, se ti piace di più. Ancora una volta, per completezza, ecco la vecchia sintassi:

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

Un altro tipo di cosa interessante da notare è che con entrambe le sintassi puoi lasciare l'ultima virgola se lo desideri, il che rende più facile copiare / incollare righe aggiuntive. Ad esempio, il seguente viene compilato correttamente:

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

5

Se stai cercando una sintassi leggermente meno prolissa, puoi creare una sottoclasse di Dictionary<string, object>(o qualunque sia il tuo tipo) come questa:

public class DebugKeyValueDict : Dictionary<string, object>
{

}

Quindi inizializza in questo modo

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

Che è equivalente a

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

Il vantaggio è che ottieni tutte le cose del tipo di compilazione che potresti desiderare, come essere in grado di dire

is DebugKeyValueDict invece di is IDictionary<string, object>

o modificare i tipi di chiave o valore in un secondo momento. Se stai facendo qualcosa di simile all'interno di una pagina cshtml razor, è molto più bello da guardare.

Oltre ad essere meno prolisso, puoi ovviamente aggiungere metodi extra a questa classe per qualsiasi cosa tu voglia.


Questo è fondamentalmente come funziona un ViewDataDictionary in MVC - stackoverflow.com/questions/607985/...
Simon_Weaver

Ho sperimentato i tipi come "alias" per Dictionarys e array tipizzati, presumendo che sarebbe stato più sicuro, in un mondo tipizzato, usare tipi predefiniti .. Si è rivelato non così utile quando si trattava di generics e linq.
Patrick

1

Nell'esempio di codice seguente, a Dictionary<TKey, TValue>viene inizializzato con istanze di tipo 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}}
  };

da msdn


-3

Sì, possiamo usare l'inizializzatore di raccolta nel dizionario Se abbiamo un dizionario come questo-

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

Possiamo inizializzarlo come segue.

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

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

            }; 

4
Ci sono già altre 6 risposte che mostrano come farlo. Non abbiamo bisogno di una settima risposta che mostri la stessa cosa.
Servy
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.