다음을 통해 공유


별칭 지시문을 사용하여 모든 종류의 형식을 참조하도록 허용

메모

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

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

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

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

요약

명명된 형식뿐만 아니라 모든 종류의 형식을 가리킬 수 있도록 using_alias_directive(§13.5.2)을 완화합니다. 이렇게 하면 튜플 형식, 포인터 형식, 배열 형식 등 현재 허용되지 않는 형식이 지원됩니다. 예를 들어 이제 허용됩니다.

using Point = (int x, int y);

동기

C#에서는 연령대에 따라 네임스페이스 및 명명된 형식(클래스, 위임, 인터페이스, 레코드 및 구조체)에 별칭을 도입할 수 있었습니다. 이는 using_directives에서 가져온 일반 이름이 모호할 수 있는 경우 충돌하지 않는 이름을 도입하는 수단을 제공했으며 복잡한 제네릭 형식을 처리할 때 더 간단한 이름을 제공할 수 있는 방법을 제공했습니다. 그러나 언어에서 추가 복합 형식 기호의 증가로 인해 별칭이 유용하지만 현재 허용되지 않는 경우 더 많은 사용이 발생합니다. 예를 들어 튜플과 함수 포인터는 모두 크고 복잡한 일반 텍스트 형식을 가질 수 있으며, 이 형식은 지속적으로 쓰기가 어려울 수 있으며 읽기를 시도해야 하는 부담이 될 수 있습니다. 별칭은 이러한 경우 개발자가 제공하는 짧은 이름을 지정하여 전체 구조 형식 대신 사용할 수 있도록 하는 데 도움이 됩니다.

상세 디자인

따라서 using_alias_directive 문법을 변경합니다.

using_alias_directive
-    : 'using' identifier '=' namespace_or_type_name ';'
+    : 'using' identifier '=' (namespace_name | type) ';'
    ;

최상위 참조 형식 null 허용 여부 주석은 허용되지 않습니다.

흥미롭게도 , §13.5.2 사양 언어의 대부분은 변경할 필요가 없습니다. 이 언어의 대부분의 언어는 이미 '네임스페이스 또는 형식'을 참조합니다. 예를 들면 다음과 같습니다.

using_alias_directive는 바로 둘러싼 컴파일 단위 또는 네임스페이스 본문 내의 네임스페이스나 형식에 대한 별칭으로 사용할 식별자를 도입합니다.

이 점은 여전히 사실입니다. 이제 문법이 'type'을 namespace_or_type_name의 제한된 집합이 아닌 임의의 형식으로 허용합니다.

업데이트해야 하는 섹션은 다음과 같습니다.

- The order in which using_alias_directives are written has no significance, and resolution of the namespace_or_type_name referenced by a using_alias_directive is not affected by the using_alias_directive itself or by other using_directives in the immediately containing compilation unit or namespace body. In other words, the namespace_or_type_name of a using_alias_directive is resolved as if the immediately containing compilation unit or namespace body had no using_directives. A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. In the example
+ The order in which using_alias_directives are written has no significance, and resolution of the `(namespace_name | type)` referenced by a using_alias_directive is not affected by the using_alias_directive itself or by other using_directives in the immediately containing compilation unit or namespace body. In other words, the `(namespace_name | type)` of a using_alias_directive is resolved as if the immediately containing compilation unit or namespace body had no using_directives. A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. In the example
- The namespace_name referenced by a using_namespace_directive is resolved in the same way as the namespace_or_type_name referenced by a using_alias_directive. Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.
+ The namespace_name referenced by a using_namespace_directive is resolved in the same way as the namespace_or_type_name referenced by a using_alias_directive. Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.
+ It is illegal for a using alias type to be a nullable reference type.

    1. `using X = string?;` is not legal.
    2. `using X = List<string?>;` is legal.  The alias is to `List<...>` which is itself not a nullable reference type itself, even though it contains one as a type argument.
    3. `using X = int?;` is legal.  This is a nullable *value* type, not a nullable *reference* type.

포인터를 포함하는 형식에 대한 별칭 지원

using_alias_directive 프로덕션에서 선택적인 'unsafe' 키워드를 통해 새 unsafe 컨텍스트가 추가됩니다.

using_alias_directive
+    : 'using' 'unsafe'? identifier '=' (namespace_name | type) ';'
    ;
    
using_static_directive
+    : 'using' 'static' 'unsafe'? type_name ';'
    ;

+ 'unsafe' can only be used with an using_alias_directive or using_static_directive, not a using_directive.
+ The 'unsafe' keyword present in a 'using_alias_directive' causes the entire textual extent of the 'type' portion (not the 'namespace_name' portion) to become an unsafe context. 
+ The 'unsafe' keyword present in a 'using_static_directive' causes the entire textual extent of the 'type_name' portion to become an unsafe context.