Ich stolperte über die folgenden und I'm wundern, warum es didn' t einen Syntaxfehler.
var dict = new Dictionary<string, object>
{
["Id"] = Guid.NewGuid(),
["Stämme"] = new List<int> { 4, 5 },
["MyA"] = new Dictionary<string, object>
{
["Name"] = "Solo",
["Punkte"] = 88
}
["OtherAs"] = new List<Dictionary<string, object> { "Name"] = "Solo", ["Punkte"] = 88 }
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
};
Beachten Sie, dass das "," zwischen dem "MyA" und "OtherAs" fehlt.
Dies ist der Grund für die Verwirrung:
Warum ist dies nicht illegal? Ist dies beabsichtigt?
Das fehlende Komma macht den entscheidenden Unterschied. Es bewirkt, dass der Indexer ["OtherAs"]
auf dieses Wörterbuch angewendet wird:
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}
Sie sagen also im Wesentlichen:
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
};
Beachten Sie, dass dies ein Zuweisungsausdruck ist (x = y
). Hier ist x
ein Wörterbuch mit "Name" und "Points", indiziert mit "OtherAs"
und y
ist die List<Dictionary<string, object>>
. Ein Zuweisungsausdruck wird auf den zugewiesenen Wert (y
) ausgewertet, der die Liste der Wörterbücher ist.
Das Ergebnis des gesamten Ausdrucks wird dann dem Schlüssel "MyA" zugewiesen, weshalb "MyA" die Liste der Wörterbücher enthält.
Sie können bestätigen, dass dies der Fall ist, indem Sie den Typ des Wörterbuchs "x" ändern:
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
}
}
Hier ist Ihr Code, aber umformatiert und mit einigen Klammern versehen, um zu veranschaulichen, wie der Compiler ihn geparst hat:
["MyA"]
=
(
(
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"]
)
=
(
new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
)
)
Was hier passiert, ist, dass Sie ein Wörterbuch erstellen und dann darin indizieren. Das Ergebnis des Indizierungs-/Zuordnungsausdrucks wird dann zurückgegeben, und das ist es, was dem Wörterbuchplatz "MyA" zugewiesen wird.
Dies:
["MyA"] = new Dictionary<string, string>
{
["Name"] = "Solo",
["Points"] = "88"
}
["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
kann in den folgenden Pseudocode aufgeteilt werden:
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
Das Ergebnis der Zuweisung an den Indexer des zweiten Wörterbuchs wird zurückgegeben (die Zuweisung gibt den zugewiesenen/rechten Wert zurück). Dieses Wörterbuch ist ein temporäres lokales, das einfach im Äther verschwindet. Das Ergebnis des Indexers (die Liste der Wörterbücher) ist das, was am Ende in das Hauptwörterbuch gestellt wird.
Dies ist ein seltsamer Fall, der durch die Verwendung von Objekt
als Typ der Wörterbuchwerte erleichtert wird.