우선은,의이 용어가 올바른하자 쉽게의 xD 작동합니다. 그건 컬렉션 이니셜 라이저가 아닙니다. 그것은 배열 초기화 프로그램입니다. 콜렉션 이니셜 라이저는 항상 콜렉션 유형의 생성자를 따릅니다. 배열 이니셜 라이저는 로컬 또는 필드 선언 초기화 프로그램이나 배열 작성 표현식에서만 유효합니다.
당신은 이것이 이상한 규칙이라는 것에 완전히 틀림 없습니다. 그 괴괴 망측을 정확하게 묘사합시다 :
int 배열을 취하는 메서드 M이 있다고합시다. 이러한 모든 법률은 다음과 같습니다
int[] x = new[] { 10, 20, 30 };
int[] y = new int[] { 10, 20, 30 };
int[] z = new int[3] { 10, 20, 30 };
M(new[] { 10, 20, 30 });
M(new int[] { 10, 20, 30 });
M(new int[3] { 10, 20, 30 });
그러나
int[] q = {10, 20, 30}; // legal!
M({ 10, 20, 30 }); // illegal!
그것은 중 하나 "고독한"배열 초기화 해야지처럼 보인다는 어디서나 하나가 없거나 곳 "장식"고 법적으로. 이상하게도 표현식이 합법적이지 않은 이니셜 라이저에서만 유효한 의사 표현식이 있습니다.
나는이 선택을 비판하고 옹호하기 전에 무엇보다도이 불일치가 역사적인 사고라고 말하고 싶습니다. 그럴만한 이유가 없습니다. 우리가 코드를 위반하지 않고 제거 할 수 있다면, 우리는 그렇게 할 것입니다. 그러나 우리는 할 수 없습니다. 우리는 C#을 처음부터 다시 디자인 했었지 만, "new"가없는 "외로운"배열 초기화 프로그램은 유효한 구문이 아닐 가능성이 높습니다.
그래서 먼저 배열 초기화 기가 표현식으로 허용되어서는 안되며 로컬 변수 초기화기에 허용되어야하는 몇 가지 이유를 알려줍니다. 그렇다면 나는 그 반대의 이유를 몇 가지 제시 할 것이다. 왜 배열 이니셜 라이저 식으로 허용되어서는 안
이유 :
배열 이니셜 라이저 {
항상 코드의 새로운 블록의 도입을 의미하는 좋은 속성을 위반. 입력 중 파싱하는 IDE의 오류 복구 구문 분석기는 명령문이 불완전한시기를 알려주는 편리한 방법으로 중괄호를 사용하는 것을 좋아합니다. 당신이 볼 경우 :
if (x == M(
{
Q(
을 코드 편집기 당신이 {
전에 ))
누락 추측하는 그 다음은 아주 간단합니다. 편집자는 Q(
이 명령문의 시작이고 그 끝이 누락되었다고 가정합니다.
그러나 배열 이니셜 라이저 법적 표현하면 다음이없는 것을 그Q
다음 )})){}
입니다 수 있습니다.
둘째, 배열 초기화 프로그램은 표현식으로 모든 힙 할당에 어딘가에 "새로운"것이 있다는 좋은 원칙을 위반합니다. 배열 이니셜 라이저는 필드와 지역의 초기화에 허용해야하는 이유
이유 :
그 배열 이니셜 라이저는 배열에, 1.0 버전의 언어 전에 암시 적으로 형식화 된 지역 주민, 익명 형식 또는 형식 유추를 추가 한 기억하십시오. 위로 하루에 우리가 가지고 있지 않은 기분 "새 [] {10, 20, 30} '구문, 당신이 말을해야 할 것 배열 이니셜 라이저가없는 있도록 : 매우 중복 보인다 int[] x = new int[] { 10, 20, 30 };
을! 나는 그들이 왜 그 "새로운 int []"을 꺼내고 싶어하는지 볼 수 있습니다.
당신이 구문 모호하지
int[] x = { 10, 20, 30 };
을 말할 때; 파서는 이것이 배열 초기화 자이며 코드 블록의 시작이 아니라는 것을 안다. (위에서 언급 한 경우와는 다르다.) 또한 타입 애매하다. 이니셜 라이저는 컨텍스트의 int 배열입니다.
이 인수는 C# 1.0에서는 배열 초기화자가 로컬 및 필드 초기화 프로그램에서 허용되지만 표현식 컨텍스트에서는 허용되지 않는 이유를 정당화합니다.
하지만 그건 우리가 현재 세계에있는 것이 아닙니다. 우리는 이것을 처음부터 디자인 했었을 것입니다. 아마 "new"가없는 배열 이니셜 라이저가 없을 것입니다. 요즘 물론 더 나은 해결책은 다음과 같습니다.
var x = new[] { 10, 20, 30 };
해당 표현식은 모든 문맥에서 유효합니다. 명시 적으로 입력하면 =
의 "선언"쪽 또는 "이니셜 라이저"쪽에 명시 적으로 입력하거나 컴파일러에서 양쪽 또는 두 가지 유형을 추측하도록 할 수 있습니다.
그렇다면 배열 초기화 프로그램은 로컬 및 필드 선언에서만 사용할 수 있지만 표현식 컨텍스트에서는 사용할 수 없다는 것은 맞습니다. 10 년 전 좋은 이유가 있었지만 형식 유추가있는 현대 세계에서는 더 이상 그럴 이유가 없습니다. 이 시점에서 역사적인 사고 일뿐입니다.
도움이 될 것입니다. http://stackoverflow.com/questions/7351453/why-cant-i-use-the-array-initializer-with-an-implicitly-typed-variable (엄격히 중복되지는 않음) –