¿Puedo usar un inicializador de colección para las entradas de Dictionary <TKey, TValue>?

94

Quiero usar un inicializador de colección para el siguiente fragmento 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;
}

Por lo general, debería ser algo como:

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

Pero, ¿cuál es la sintaxis correcta para esto?

Gerrie Schenck
fuente
Consulte esta publicación: marcin-chwedczuk.github.io/…
csharpfolk
no crea que es un engaño, porque estaban preguntando, no por la sintaxis de declaración del diccionario de taquigrafía, sino por qué la taquigrafía no funcionaba en su configuración (antigua).
NH.

Respuestas:

157
var names = new Dictionary<int, string> {
  { 1, "Adam" },
  { 2, "Bart" },
  { 3, "Charlie" }
};
bruno conde
fuente
1
¿Cuándo funciona el inicializador? ¿Es solo para Dictionary<TKey, TValue>subclases o también funcionará ICollection<KeyValuePair<TKey, TValue>>?
Shimmy Weitzhandler
después de C # 3.0, puede usar en varlugar del tipo de declaración, o si dejar el tipo de declaración puede omitir el new Dictio...- stackoverflow.com/questions/5678216/…
drzaus
1
@drzaus: Sin embargo, usar var es una práctica fea; C # es un lenguaje fuertemente tipado.
Nyerguds
1
@Nyerguds: ¿qué? varliteralmente solo te ahorra las pulsaciones de teclas, está implícitamente tecleado fuertemente .
drzaus
4
@Nyerguds: tienes derecho a tu opinión, supongo, pero si estás inicializando tus variables inmediatamente, literalmente no hay diferencia entre usar vary repetirte SomeType obj = new SomeType.... Y dado que no puede declarar var obj;sin inicializar inmediatamente, simplemente no veo el problema. Realmente, estoy tratando de aprender, pero no puedo asimilar tu posición.
drzaus
36

La sintaxis es ligeramente diferente:

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

Tenga en cuenta que está agregando tuplas de valores de manera efectiva.

Como nota al margen: los inicializadores de colección contienen argumentos que son básicamente argumentos para cualquier función Add () que sea útil con respecto al tipo de argumento en tiempo de compilación. Es decir, si tengo una colección:

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

    public void Add(string s) ...

    public void Add(double d) ...
}

el siguiente código es perfectamente legal:

var foos = new FooCollection() { 1, 2, 3.14, "Hello, world!" };
Anton Gogolev
fuente
Gran respuesta, ¡no sabía nada de eso! De todos modos, ¿cuándo funciona el inicializador del diccionario? ¿Es solo para las subclases Dictionary <TKey, TValue> o también funcionará en ICollection <KeyValuePair <TKey, TValue >>?
Shimmy Weitzhandler
Los inicializadores de @Shimmy Collection funcionan en cualquier cosa que implemente IEnumerable y tenga Add()métodos.
Anton Gogolev
@Shimmy: los diccionarios son colecciones
John Saunders
@JohnSaunders Pero un inicializador de diccionario acepta dos parámetros para Add.
Shimmy Weitzhandler
2
@Shimmy: ¿por qué importa eso? El punto es que funcionará con cualquier clase que implemente IEnumerable<T>y que tenga un Addmétodo. Si el Addmétodo toma 3 parámetros, entonces necesitará 3 objetos entre paréntesis.
John Saunders
11
return new Dictionary<int, string>
{ 
   { 1, "Adam" },
   { 2, "Bart" },
   ...
ybo
fuente
10

La pregunta está etiquetada c#-3.0, pero para completar, mencionaré la nueva sintaxis disponible con C # 6 en caso de que esté utilizando Visual Studio 2015 (o Mono 4.0):

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

Nota: la sintaxis anterior mencionada en otras respuestas aún funciona, si te gusta más. Nuevamente, para completar, aquí está la sintaxis anterior:

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

Otra cosa interesante a tener en cuenta es que con cualquier sintaxis puede dejar la última coma si lo desea, lo que facilita copiar / pegar líneas adicionales. Por ejemplo, lo siguiente se compila muy bien:

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

Si está buscando una sintaxis un poco menos detallada, puede crear una subclase de Dictionary<string, object>(o del tipo que sea) como esta:

public class DebugKeyValueDict : Dictionary<string, object>
{

}

Entonces solo inicializa así

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

Que es equivalente a

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

El beneficio es que obtienes todo el tipo de compilación que podrías desear, como poder decir

is DebugKeyValueDict en vez de is IDictionary<string, object>

o cambiar los tipos de clave o valor en una fecha posterior. Si está haciendo algo como esto dentro de una página cshtml de razor, es mucho más agradable de ver.

Además de ser menos detallado, por supuesto, puede agregar métodos adicionales a esta clase para lo que desee.

Simon_Weaver
fuente
Se trata básicamente de cómo un ViewDataDictionary trabaja en MVC - stackoverflow.com/questions/607985/...
Simon_Weaver
Experimenté con tipos como 'alias' para Dictionarys y matrices tipadas, asumiendo que sería más seguro, en un mundo tipado, usar tipos predefinidos. Resultó no ser tan útil cuando se trataba de genéricos y linq.
Patrick
1

En el siguiente ejemplo de código, a Dictionary<TKey, TValue>se inicializa con instancias de 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}}
  };

de msdn

Bellash
fuente
-3

Sí, podemos usar el inicializador de colección en el diccionario.Si tenemos un diccionario 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 inicializarlo de la siguiente manera.

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

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

            }; 
Debendra Dash
fuente
4
Ya hay otras 6 respuestas que muestran cómo hacer esto. No necesitamos una séptima respuesta que muestre lo mismo.
Servicio