¿Cómo es de correcta esta inicialización del diccionario de C#?

Me he encontrado con lo siguiente y me pregunto por qué no ha dado un error de sintaxis.

var dict = new Dictionary<string, object>
{
    ["Id"] = Guid.NewGuid(),
    ["Tribus"] = new List<int> { 4, 5 },
    ["MyA"] = new Dictionary<string, object>
    {
        ["Nombre"] = "Solo",
        ["Puntos"] = 88
    }
    ["OtrosAs"] = new List<Dictionary<string, object>>
    {
        nuevo Dictionary<string, object>
        {
            ["Puntos"] = 1999
        }
    }
};

Fíjate en que falta el "," entre el "MiA", y el "OtroAs".

Aquí es donde se produce la confusión:

  1. El código se compila.
  2. El diccionario final "dict" contiene sólo tres elementos: "Id", "Tribus", y "MiA".
  3. Los valores de todos los elementos, excepto "MiA", son correctos,
  4. "MiA" toma el valor declarado para "OtrosA", mientras que su valor original se ignora.

¿Por qué no es esto ilegal? ¿Es esto por el diseño?

Comentarios sobre la pregunta (9)
Solución

La coma que falta marca la diferencia. Hace que el indexador ["OtrosAs"] se aplique en este diccionario:

new Dictionary
{
    ["Name"] = "Solo",
    ["Points"] = 88
}

Así que, esencialmente, estás diciendo:

new Dictionary
{
    ["Name"] = "Solo",
    ["Points"] = 88
}["OtherAs"] = new List
{
    new Dictionary
    {
        ["Points"] = 1999
    }
};

Tenga en cuenta que esta es una expresión de asignación (x = y). Aquí x es un diccionario con "Nombre" y "Puntos", indexado con "OtrosAs"yyes laLista

Comentarios (2)

Lo que ocurre aquí es que está creando un diccionario y luego indexando en él. El resultado de la expresión de indexación/asignación se devuelve y es lo que se asigna a la ranura del diccionario MiA.

Esto:

["MyA"] = new Dictionary 
{
   ["Name"] = "Solo",
   ["Points"] = "88" 
}
["OtherAs"] = new List
{
   new Dictionary
   {
       ["Points"] = 1999
   }
}

Se puede dividir en el siguiente psuedo-código:

var temp = new Dictionary
{ 
   ["Name"] = "Solo", 
   ["Points"] = 88 
};
// indexed contains result of assignment
var indexed = temp["OtherAs"] = new List
{
   new Dictionary
   {
      ["Points"] = 1999
   }
};
// value is set to result of assignment from previous step
["MyA"] = indexed;
// temp is discarded

Se devuelve el resultado de la asignación al indexador del segundo diccionario (la asignación devuelve el valor asignado/derecho) Ese diccionario es un local temporal que simplemente "desaparece en el éter". El resultado del indexador (la lista de diccionarios) es lo que se coloca en el diccionario principal al final.

Este es un caso raro, en el que es más fácil caer debido al uso de object como tipo de los valores del diccionario.

Comentarios (0)