次の方法で共有


エイリアス ディレクティブを使用して任意の種類の型を参照できるようにする

手記

この記事は機能仕様です。 仕様は、機能の設計ドキュメントとして機能します。 これには、提案された仕様の変更と、機能の設計と開発時に必要な情報が含まれます。 これらの記事は、提案された仕様の変更が最終決定され、現在の ECMA 仕様に組み込まれるまで公開されます。

機能の仕様と完成した実装の間には、いくつかの違いがある可能性があります。 これらの違いは、関連する 言語設計会議 (LDM) ノートでキャプチャされます。

機能仕様を C# 言語標準に導入するプロセスの詳細については、仕様に関する記事を参照してください。

チャンピオンの課題: https://github.com/dotnet/csharplang/issues/8645

概要

using_alias_directive (§13.5.2) の制限を緩め、名前付き型に限定せず、任意の型を指せるようにします。 これは、タプル型、ポインター型、配列型など、現在許可されていない型をサポートします。たとえば、次の操作が許可されます。

using Point = (int x, int y);

モチベーション

長い間、C# には名前空間と名前付き型 (クラス、デリゲート、インターフェイス、レコード、構造体) のエイリアスを導入する機能がありました。 これは、using_directiveからプルされた通常の名前があいまいになる場合や、複雑なジェネリック型を扱うときに、競合しない名前を導入する手段を提供し、またより単純な名前を指定できる方法として十分に役立ちました。 ただし、言語における複合型シンボルの増加により、エイリアスが有益でありながら現時点では認められない場面での使用が増えています。 たとえば、タプルと関数ポインターの両方に、多くの場合、大量の複雑な通常のテキスト形式があり、継続的に書き出すのに苦しい場合があり、読み取りを試みる負担を伴う場合があります。 エイリアスは、これらの完全な構造形式の代わりに使用できる、開発者が提供する短い名前を付けることで、このような場合に役立ちます。

詳細な設計

このように 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' キーワードを使用して追加されます。

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.