¿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?


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

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

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" },
   ...

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

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.


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


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

            }; 

4
Ya hay otras 6 respuestas que muestran cómo hacer esto. No necesitamos una séptima respuesta que muestre lo mismo.
Servicio
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.