Dan*_*tte 64 c# dictionary initialization
我偶然发现了以下内容,我想知道为什么它没有引发语法错误。
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
}
}
};
Run Code Online (Sandbox Code Playgroud)
请注意,“MyA”和“OtherAs”之间缺少“,”。
这就是混乱发生的地方:
为什么这不违法?这是故意的吗?
Swe*_*per 55
缺少的逗号使一切变得不同。它导致索引器["OtherAs"]应用于此字典:
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}
Run Code Online (Sandbox Code Playgroud)
所以基本上你是说:
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
};
Run Code Online (Sandbox Code Playgroud)
请注意,这是一个赋值表达式 ( x = y)。这x是带有“名称”和“点”的字典,以"OtherAs"和y为索引List<Dictionary<string, object>>。赋值表达式的计算结果为被赋值的值 ( y),即字典列表。
然后将整个表达式的结果分配给键“MyA”,这就是“MyA”具有字典列表的原因。
您可以通过更改字典的类型来确认这是正在发生的事情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
}
}
Run Code Online (Sandbox Code Playgroud)
这是您的代码,但已重新格式化并添加了一些括号以说明编译器如何解析它:
["MyA"]
=
(
(
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"]
)
=
(
new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
)
)
Run Code Online (Sandbox Code Playgroud)
pin*_*x33 20
这里发生的事情是您正在创建一个字典,然后对其进行索引。然后返回索引器/分配表达式的结果,这就是分配到MyA字典槽中的内容。
这个:
["MyA"] = new Dictionary<string, string>
{
["Name"] = "Solo",
["Points"] = "88"
}
["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
Run Code Online (Sandbox Code Playgroud)
可以拆分为以下伪代码:
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
Run Code Online (Sandbox Code Playgroud)
返回分配给第二个字典的索引器的结果(分配返回分配的值/右侧)该字典是一个临时本地,只是“消失在以太中”。索引器的结果(字典列表)是最后放入主字典的内容。
这是一个奇怪的情况,由于使用objectas 字典值的类型,更容易陷入这种情况。