简体   繁体   English

这个 C# 字典初始化如何正确?

[英]How is this C# dictionary initialization correct?

I stumbled upon the following and I'm wondering why it didn't raise a syntax error.我偶然发现了以下内容,我想知道为什么它没有引发语法错误。

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
        }
    }
};

Notice that the "," is missing between the "MyA", and "OtherAs".请注意,“MyA”和“OtherAs”之间缺少“,”。

This is where the confusion happens:这就是混乱发生的地方:

  1. The code compiles.代码编译。
  2. The final dictionary "dict" contains only three elements: "Id", "Tribes", and "MyA".最终字典“dict”仅包含三个元素:“Id”、“Tribes”和“MyA”。
  3. The value for all except "MyA" are correct,除了“MyA”之外的所有值都是正确的,
  4. "MyA" takes the declared value for "OtherAs", while its original value is ignored. “MyA”采用“OtherAs”的声明值,而忽略其原始值。

Why isn't this illegal?为什么这不违法? Is this by design?这是故意的吗?

The missing comma makes all the difference.缺少的逗号使一切变得不同。 It causes the indexer ["OtherAs"] to be applied on this dictionary:它导致索引器["OtherAs"]应用于此字典:

new Dictionary<string, object>
{
    ["Name"] = "Solo",
    ["Points"] = 88
}

So essentially you're saying:所以基本上你是说:

new Dictionary<string, object>
{
    ["Name"] = "Solo",
    ["Points"] = 88
}["OtherAs"] = new List<Dictionary<string, object>>
{
    new Dictionary<string, object>
    {
        ["Points"] = 1999
    }
};

Note that this is an assignment expression ( x = y ).请注意,这是一个赋值表达式 ( x = y )。 Here x is dictionary with "Name" and "Points", indexed with "OtherAs" and y is the List<Dictionary<string, object>> .这里x是带有“名称”和“点”的字典,用"OtherAs"索引, yList<Dictionary<string, object>> An assignment expression evaluates to the value being assigned ( y ), which is the list of dictionaries.赋值表达式的计算结果为被赋值的值 ( y ),即字典列表。

The result of this whole expression is then assigned to the key "MyA", which is why "MyA" has the list of dictionaries.然后将整个表达式的结果分配给键“MyA”,这就是“MyA”具有字典列表的原因。

You can confirm that this is what's happening by changing the type of the dictionary x :您可以通过更改字典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
    }
}

Here is your code, but reformatted and some parentheses added to illustrated how the compiler has parsed it:这是您的代码,但已重新格式化并添加了一些括号以说明编译器如何解析它:

["MyA"] 
= 
(
    (
        new Dictionary<string, object>
        {
            ["Name"] = "Solo",
            ["Points"] = 88
        }["OtherAs"] 
    )
    = 
    (
        new List<Dictionary<string, object>>
        {
            new Dictionary<string, object>
            {
                ["Points"] = 1999
            }
        }
    )
)

What's happening here is that you are creating a dictionary and then indexing into it.这里发生的事情是您正在创建一个字典,然后对其进行索引。 The result of the indexer/assignment expression is then returned and that is what is getting assigned into the MyA dictionary slot.然后返回索引器/分配表达式的结果,这就是分配到MyA字典槽中的内容。

This:这个:

["MyA"] = new Dictionary<string, string> 
{
   ["Name"] = "Solo",
   ["Points"] = "88" 
}
["OtherAs"] = new List<Dictionary<string, object>>
{
   new Dictionary<string, object>
   {
       ["Points"] = 1999
   }
}

Can be split out into the following psuedo-code:可以拆分为以下伪代码:

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

The result of assigning to the indexer of the second dictionary is returned (the assignment returns the value assigned/right hand side) That dictionary is a temporary local that just "disappears into the ether".返回分配给第二个字典的索引器的结果(分配返回分配的值/右侧)该字典是一个临时本地,只是“消失在以太中”。 The result of the indexer (the list of dictionaries) is what is placed into the main dictionary in the end.索引器的结果(字典列表)是最后放入主字典的内容。

This is a weird case, which is made easier to fall into due to the use of object as the type of the dictionary values.这是一个奇怪的情况,由于使用object作为字典值的类型,因此更容易陷入困境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM