簡體   English   中英

這個 C# 字典初始化如何正確?

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

我偶然發現了以下內容,我想知道為什么它沒有引發語法錯誤。

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”之間缺少“,”。

這就是混亂發生的地方:

  1. 代碼編譯。
  2. 最終字典“dict”僅包含三個元素:“Id”、“Tribes”和“MyA”。
  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是帶有“名稱”和“點”的字典,用"OtherAs"索引, yList<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作為字典值的類型,因此更容易陷入困境。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM