다음을 통해 공유


대상 유형 new 표현식

메모

이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.

기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 이러한 차이는 관련LDM(언어 디자인 모임) 노트에서 캡처됩니다.

사양에 대한 기사에서 C# 언어 표준으로 기능 사양서를 채택하는 프로세스에 대해 자세히 알아볼 수 있습니다.

챔피언 이슈: https://github.com/dotnet/csharplang/issues/100

요약

형식이 알려진 경우 생성자에 대한 형식 사양이 필요하지 않습니다.

동기

형식을 복제하지 않고 필드 초기화를 허용합니다.

Dictionary<string, List<int>> field = new() {
    { "item1", new() { 1, 2, 3 } }
};

사용에서 유추할 수 있는 경우 형식을 생략할 수 있습니다.

XmlReader.Create(reader, new() { IgnoreWhitespace = true });

형식의 철자를 지정하지 않고 개체를 인스턴스화합니다.

private readonly static object s_syncObj = new();

사양

새로운 구문 형식 target_typed_new이 허용되며, 여기서 object_creation_expression형식은 선택 사항입니다.

object_creation_expression
    : 'new' type '(' argument_list? ')' object_or_collection_initializer?
    | 'new' type object_or_collection_initializer
    | target_typed_new
    ;
target_typed_new
    : 'new' '(' argument_list? ')' object_or_collection_initializer?
    ;

target_typed_new 식에는 형식이 없습니다. 그러나 새로운 개체 만들기 변환은 모든 형식으로의 target_typed_new에서 표현식에서의 암시적 변환입니다.

타입 T이 주어졌을 때, TSystem.Nullable의 인스턴스인 경우, 타입 T0T의 기본 형식입니다. 그렇지 않으면 T0T이다. T 유형으로 변환된 target_typed_new 식의 의미는, T0 유형으로 지정된 대응하는 object_creation_expression의 의미와 동일합니다.

target_typed_new가 단항 또는 이진 연산자의 피연산자로 사용되거나, 개체 생성 변환의 대상이 아닌 곳에서 사용되는 경우, 컴파일 시간 오류가 발생합니다.

열린 문제: 대리자와 튜플을 대상 형식으로 허용해야 하나요?

위의 규칙에는 대리자(참조 형식) 및 튜플(구조체 형식)이 포함됩니다. 두 형식 모두 생성 가능하지만 형식을 유추할 수 있는 경우 익명 함수 또는 튜플 리터럴을 이미 사용할 수 있습니다.

(int a, int b) t = new(1, 2); // "new" is redundant
Action a = new(() => {}); // "new" is redundant

(int a, int b) t = new(); // OK; same as (0, 0)
Action a = new(); // no constructor found

잡다한

사양의 결과는 다음과 같습니다.

  • throw new() 허용됩니다(대상 형식이 System.Exception).
  • 타겟 타입 new는 이진 연산자와 함께 사용할 수 없습니다.
  • 대상으로 지정할 형식이 없는 경우 허용되지 않습니다: 단항 연산자, foreach의 컬렉션, using의 경우, 해체에서, await 표현식에서, 익명 형식 속성 (new { Prop = new() })으로, lock 문 안에서, sizeof에서, fixed 문 안에서, 멤버 액세스 (new().field) 시, 동적으로 디스패치된 작업 (someDynamic.Method(new()))에서, LINQ 쿼리에서, is 연산자의 피연산자로, ?? 연산자의 왼쪽 피연산자로 ...
  • 또한 ref으로서 허용되지 않습니다.
  • 다음 종류의 형식은 변환의 대상으로 허용되지 않습니다.
    • 열거형 형식:new() 작동하지만(new Enum() 기본값을 제공하기 위해 작동함) 열거형 형식에 생성자가 없으므로 new(1) 작동하지 않습니다.
    • 인터페이스 형식: COM 형식에 대한 해당 생성 식과 동일하게 작동합니다.
    • 배열 형식: 배열은 길이를 제공하기 위해 특수 구문이 필요합니다.
    • 동적: new dynamic()허용하지 않는dynamic 대상 형식으로 new() 허용하지 않습니다.
    • 튜플: 기본 형식을 사용하여 개체를 만드는 것과 동일한 의미를 갖습니다.
    • object_creation_expression 허용되지 않는 다른 모든 형식도 제외됩니다(예: 포인터 형식).

단점

대상 형식 new가 새로운 불호환 변경 범주를 만들어내는 것에 대한 몇 가지 우려가 있었지만, 우리는 이미 nulldefault에서 이런 변경을 경험했으며 그것이 큰 문제가 되진 않았습니다.

대안

필드 초기화에서 중복하기에 너무 긴 형식에 대한 불만의 대부분은 형식 자체가 아닌 형식 인수에 관한, new Dictionary(...)(또는 이와 유사한) 형식 인수만 유추하고 인수 또는 컬렉션 이니셜라이저에서 로컬로 형식 인수를 유추할 수 있습니다.

질문

  • 표현식 트리의 사용을 금지해야 하나요? (아니요)
  • 기능이 dynamic 인수와 상호 작용하는 방법 (특별한 대우 없음)
  • IntelliSense가 new()에 대해 어떻게 작동해야 하나요? (단일 대상 유형이 있는 경우에만)

디자인 회의