Я наткнулся на следующее, и мне интересно, почему это не вызывает синтаксическую ошибку.
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
}
}
};
Обратите внимание, что "," отсутствует между "MyA" и "OtherAs".
Вот где происходит путаница:
- Код компилируется.
- Окончательный словарь «dict» содержит только три элемента: «Id», «Tribes» и «MyA».
- Значение для всех, кроме "MyA", является правильным,
- «MyA» принимает объявленное значение для «OtherAs», а его исходное значение игнорируется.
Почему это не незаконно? Это по замыслу?
c#
dictionary
initialization
Dantte
источник
источник
OtherAs
добавляется в качестве ключа в то , что будетMyA
словарь. (Name = Solo, Points = 88 плюс OtherAs = List <Dictionary <string, object >>) за исключением того, что оно никогда не назначает его . Вместо этого он помещает список диктов, теперь содержащий только одну запись Points = 1999, вMyA
ячейку, переопределяющую то, что, как можно подумать, принадлежит ей.<string, string> and modify Points to
«88», то «получите ошибку компилятора». Невозможно неявно преобразовать тип 'System.Collections.Generic.List <System.Collections.Generic.Dictionary <string, object >>' в 'string' " что на самом деле помогло мне понять ответ!var test = new Dictionary<string, object> { ["Name"] = "Solo", ["Points"] = 88 }["OtherAs"] = new List<Dictionary<string, object>> { new Dictionary<string, object> { ["Points"] = 1999 } };
, объясню это дальше.Ответы:
Отсутствующая запятая имеет все значение. Это заставляет индексатор
["OtherAs"]
быть примененным к этому словарю:По сути, вы говорите:
Обратите внимание, что это выражение присваивания (
x = y
). Вотx
словарь с именами и точками, проиндексирован"OtherAs"
иy
обозначенList<Dictionary<string, object>>
. Выражение присваивания оценивается как значение (y
), которое является списком словарей.Результат всего этого выражения затем назначается клавише «MyA», поэтому у «MyA» есть список словарей.
Вы можете подтвердить, что это то, что происходит, изменив тип словаря
x
:Вот ваш код, но он переформатирован и добавлены некоторые скобки, чтобы проиллюстрировать, как его проанализировал компилятор:
источник
object
к ,string
который дал мне подобное сообщение об ошибке и ага момент , который вызвал ответ. Кажется, ты меня побил - я обвиняю, что набрал ответ на своем телефоне :-pЗдесь происходит то, что вы создаете словарь, а затем индексируете его. Затем возвращается результат выражения индексатора / присваивания, и именно это присваивается в
MyA
слоте словаря.Эта:
Может быть разбит на следующий псевдо-код:
Возвращается результат присваивания индексатору второго словаря (присваивание возвращает присвоенное значение / правая часть). Этот словарь является временным локальным, который просто «исчезает в эфире». Результатом индексатора (списка словарей) является то, что в конце помещается в основной словарь.
Это странный случай, в который легче попасть из-за использования в
object
качестве типа значений словаря.источник