Posso usar um inicializador de coleção para entradas de Dictionary <TKey, TValue>?

94

Quero usar um inicializador de coleção para o próximo trecho de código:

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

Normalmente, deve ser algo como:

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

Mas qual é a sintaxe correta para isso?

Gerrie Schenck
fonte
Verifique esta postagem: marcin-chwedczuk.github.io/…
csharpfolk
não pense que isso é um tolo, porque eles estavam perguntando, não pela sintaxe de declaração do dicionário abreviado, mas por que a abreviação não estava funcionando em sua configuração (antiga).
NH.

Respostas:

157
var names = new Dictionary<int, string> {
  { 1, "Adam" },
  { 2, "Bart" },
  { 3, "Charlie" }
};
bruno conde
fonte
1
Quando o inicializador funciona? É apenas para Dictionary<TKey, TValue>subclasses ou também funcionará ICollection<KeyValuePair<TKey, TValue>>?
Shimmy Weitzhandler
após o C # 3.0, você pode usar em varvez do tipo new Dictio...
declarativo
1
@drzaus: No entanto, usar var é uma prática feia; C # é uma linguagem fortemente tipada.
Nyerguds
1
@Nyerguds: o quê? varliteralmente apenas economiza pressionamentos de teclas, é implicitamente fortemente digitado .
drzaus
4
@Nyerguds - você tem direito à sua opinião, eu acho, mas se você está inicializando imediatamente suas variáveis, não há literalmente nenhuma diferença entre usar vare se repetir com SomeType obj = new SomeType.... E como você não pode declarar var obj;sem inicializar imediatamente, não vejo o problema. Realmente, estou tentando aprender, mas não consigo grocar sua posição.
drzaus 01 de
36

A sintaxe é um pouco diferente:

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

Observe que você está efetivamente adicionando tuplas de valores.

Como nota lateral: os inicializadores de coleção contêm argumentos que são basicamente argumentos para qualquer função Add () que seja útil em relação ao tipo de argumento em tempo de compilação. Ou seja, se eu tiver uma coleção:

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

    public void Add(string s) ...

    public void Add(double d) ...
}

o código a seguir é perfeitamente legal:

var foos = new FooCollection() { 1, 2, 3.14, "Hello, world!" };
Anton Gogolev
fonte
Ótima resposta, eu não sabia disso! De qualquer forma, quando o inicializador de dicionário funciona? É apenas para subclasses de Dictionary <TKey, TValue> ou também funcionará em ICollection <KeyValuePair <TKey, TValue >>?
Shimmy Weitzhandler
Os inicializadores da coleção @Shimmy funcionam em qualquer coisa que implemente IEnumerable e tenha Add()métodos.
Anton Gogolev
@Shimmy: dicionários são coleções
John Saunders
@JohnSaunders Mas um inicializador de dicionário aceita dois parâmetros para Add.
Shimmy Weitzhandler
2
@Shimmy: por que isso importa? A questão é que funcionará com qualquer classe que implemente IEnumerable<T>e que tenha um Addmétodo. Se o Addmétodo tiver 3 parâmetros, você precisará de 3 objetos entre colchetes.
John Saunders
11
return new Dictionary<int, string>
{ 
   { 1, "Adam" },
   { 2, "Bart" },
   ...
ybo
fonte
10

A pergunta está marcada c#-3.0, mas para completar, mencionarei a nova sintaxe disponível com C # 6 caso você esteja usando o Visual Studio 2015 (ou Mono 4.0):

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

Nota: a sintaxe antiga mencionada em outras respostas ainda funciona, se você preferir. Novamente, para ser completo, aqui está a sintaxe antiga:

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

Outro tipo de coisa interessante a se notar é que com qualquer sintaxe você pode deixar a última vírgula se desejar, o que torna mais fácil copiar / colar linhas adicionais. Por exemplo, o seguinte compila perfeitamente:

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

Se você está procurando uma sintaxe um pouco menos detalhada, pode criar uma subclasse de Dictionary<string, object>(ou qualquer que seja o seu tipo) como esta:

public class DebugKeyValueDict : Dictionary<string, object>
{

}

Então é só inicializar assim

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

Que é equivalente a

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

A vantagem é que você obtém todas as coisas do tipo de compilação que você pode querer, como ser capaz de dizer

is DebugKeyValueDict ao invés de is IDictionary<string, object>

ou alterando os tipos de chave ou valor em uma data posterior. Se você estiver fazendo algo assim em uma página cshtml do razor, é muito mais agradável de olhar.

Além de ser menos prolixo, você pode adicionar métodos extras a esta classe para o que quiser.

Simon_Weaver
fonte
É basicamente assim que um ViewDataDictionary funciona no MVC - stackoverflow.com/questions/607985/…
Simon_Weaver
Experimentei tipos como 'aliases' para dicionários e matrizes digitadas, presumindo que seria mais seguro, em um mundo digitado, usar tipos predefinidos. Acabou não sendo tão útil quando se tratava de genéricos e linq.
Patrick
1

No exemplo de código a seguir, a Dictionary<TKey, TValue>é inicializado com instâncias do 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}}
  };

do msdn

Bellash
fonte
-3

Sim, podemos usar o inicializador de coleção no dicionário. Se tivermos um dicionário como este-

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

Podemos inicializá-lo como segue.

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

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

            }; 
Debendra Dash
fonte
4
Já existem 6 outras respostas mostrando como fazer isso. Não precisamos de uma 7ª resposta mostrando a mesma coisa.
Servy