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:
¿Por qué no es esto ilegal? ¿Es esto por el diseño?
La coma que falta marca la diferencia. Hace que el indexador ["OtrosAs"]
se aplique en este diccionario:
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}
Así que, esencialmente, estás diciendo:
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["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"y
yes la
Lista<de diccionarios<de cadenas, de objetos<. Una expresión de asignación se evalúa al valor que se asigna (y
), que es la lista de diccionarios.
El resultado de toda esta expresión se asigna entonces a la clave "MiA", por lo que "MiA" tiene la lista de diccionarios.
Puede confirmar que esto es lo que ocurre cambiando el tipo del diccionario x
:
new Dictionary<int, object>
{
[1] = "Solo",
[2] = 88
}
// compiler error saying "can't convert string to int"
// so indeed this indexer is applied to the previous dictionary
["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
Aquí está tu código, pero reformateado y con algunos paréntesis añadidos para ilustrar cómo el compilador lo ha analizado:
["MyA"]
=
(
(
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"]
)
=
(
new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
)
)
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<string, string>
{
["Name"] = "Solo",
["Points"] = "88"
}
["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
Se puede dividir en el siguiente psuedo-código:
var temp = new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
};
// indexed contains result of assignment
var indexed = temp["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["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.