[c#] 이 C # 사전 초기화는 어떻게 정확합니까?

나는 다음을 우연히 발견하고 왜 구문 오류가 발생하지 않았는지 궁금합니다.

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"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사전 값의 유형으로 사용하기 때문에 더 쉽게 빠질 수있는 이상한 경우 입니다.


답변