Natknąłem się na następujące i zastanawiam się, dlaczego nie spowodowało to błędu składniowego.
var dict = new Dictionary<string, object>
{
["Id"] = Guid.NewGuid(),
["Tribes"] = new List<int> { 4, 5 },
["MyA"] = new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}
["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
};
Zauważ, że między „MyA” i „OtherAs” brakuje „,”.
W tym miejscu dochodzi do zamieszania:
- Kod się kompiluje.
- Ostatni słownik „dict” zawiera tylko trzy elementy: „Id”, „Tribes” i „MyA”.
- Wartości dla wszystkich oprócz „MyA” są poprawne,
- „MyA” przyjmuje zadeklarowaną wartość dla „OtherAs”, a jej pierwotna wartość jest ignorowana.
Dlaczego to nie jest nielegalne? Czy to z założenia?
c#
dictionary
initialization
Dantte
źródło
źródło
OtherAs
zostanie dodany jako klucz do tego, co byłobyMyA
słownika. (Name = Solo, Points = 88 plus OtherAs = List <Dictionary <string, object >>), ale nigdy nie przypisuje go . Zamiast tego umieszcza listę nagrań, teraz zawierającą tylko jeden wpis Punkty = 1999 wMyA
gnieździe, zastępując to, co według nich należy.<string, string> and modify Points to
„88”, pojawi się błąd kompilatora „Nie można niejawnie przekonwertować typu„ System.Collections.Generic.List <System.Collections.Generic.Dictionary <ciąg, obiekt >> ”na„ ciąg ” co faktycznie pomogło mi znaleźć odpowiedź!var test = new Dictionary<string, object> { ["Name"] = "Solo", ["Points"] = 88 }["OtherAs"] = new List<Dictionary<string, object>> { new Dictionary<string, object> { ["Points"] = 1999 } };
, wyjaśnię to dalej.Odpowiedzi:
Brakujący przecinek robi różnicę. Powoduje to zastosowanie indeksu
["OtherAs"]
do tego słownika:Więc zasadniczo mówisz:
Zauważ, że jest to wyrażenie przypisania (
x = y
). Otox
słownik z „Nazwa” i „Punkty”, indeksowany za pomocą"OtherAs"
iy
jestList<Dictionary<string, object>>
. Wyrażenie przypisania ocenia na wartość przypisywaną (y
), która jest listą słowników.Wynik tego całego wyrażenia jest następnie przypisywany do klawisza „MyA”, dlatego „MyA” ma listę słowników.
Możesz potwierdzić, że tak się dzieje, zmieniając typ słownika
x
:Oto twój kod, ale został ponownie sformatowany i dodano kilka nawiasów ilustrujących, w jaki sposób kompilator go przeanalizował:
źródło
object
na,string
co dało mi podobny komunikat o błędzie i moment aha, który wywołał odpowiedź. Wygląda na to, że mnie pobiłaśTo, co się tutaj dzieje, polega na tym, że tworzysz słownik, a następnie indeksujesz go. Wynik wyrażenia indeksującego / przypisania jest następnie zwracany i to właśnie jest przypisywane do
MyA
szczeliny słownika.To:
Można podzielić na następujący kod psuedo:
Zwracany jest wynik przypisania do indeksatora drugiego słownika (przypisanie zwraca wartość przypisaną / prawą stronę). Ten słownik jest tymczasowym lokalnym, który po prostu „znika w eterze”. Wynik indeksu (lista słowników) znajduje się na końcu w słowniku głównym.
To dziwny przypadek, do którego łatwiej jest wpaść ze względu na użycie
object
jako typu wartości słownika.źródło