나는 다음을 우연히 발견하고 왜 구문 오류가 발생하지 않았는지 궁금합니다.
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”사이에 “,”가 없습니다.
혼란이 일어나는 곳입니다.
- 코드가 컴파일됩니다.
- 마지막 사전 “dict”에는 “Id”, “Tribes”및 “MyA”의 세 가지 요소 만 포함됩니다.
- “MyA”를 제외한 모든 값이 정확합니다.
- “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
사전 값의 유형으로 사용하기 때문에 더 쉽게 빠질 수있는 이상한 경우 입니다.