我偶然发现了以下内容,我想知道为什么它没有引发语法错误。
var dict = new Dictionary<string, object>
{
["Id"] = Guid.NewGuid()。
["Tribes"] = new List<int> { 4, 5 },
["MyA"] = new Dictionary<string, object>
{
["Name"] = "Solo",
["点数"] = 88
}
["OtherAs"] = 新的List<Dictionary<string, object>>
{
新字典<字符串,对象>
{
["Points"] = 1999
}
}
};
注意,在"MyA"和"OtherAs"之间缺少","。
这就是发生混淆的地方。
1.该代码可以编译。 2.2.最终的字典"dict"只包含三个元素:"Id","Tribes",和"MyA"。 3.3. 除了"MyA"之外,其他的值都是正确的。 4."MyA"采用"OtherAs"的声明值,而其原始值被忽略。
为什么这不违法呢?这是在设计中吗?
缺少的逗号造成了所有的不同。它导致索引器["OtherAs"]
被应用在这个字典上。
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}
所以从本质上说,你是在说。
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
};
注意,这是一个赋值表达式(x = y
)。这里x
是带有"Name"和"Points"的字典,以"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
}
}
这是你的代码,但经过重新格式化,并添加了一些括号以说明编译器是如何解析的。
["MyA"]
=
(
(
new Dictionary<string, object>
{
["Name"] = "Solo",
["Points"] = 88
}["OtherAs"]
)
=
(
new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
)
)
这里发生的情况是,你正在创建一个字典,然后对它进行索引。索引器/赋值表达式的结果被返回,这就是被赋值到 MyA
字典槽中的东西。
这一点。
["MyA"] = new Dictionary<string, string>
{
["Name"] = "Solo",
["Points"] = "88"
}
["OtherAs"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
["Points"] = 1999
}
}
可以拆分成以下的伪代码。
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
赋值给第二个字典的索引器的结果被返回(赋值返回赋值/右手)那个字典是一个临时的局部,只是"消失在乙醚中"。索引器的结果(字典的列表)就是最后被放入主字典的东西。
这是一个奇怪的情况,由于使用了 object
作为字典值的类型,所以更容易陷入其中。