允許使用別名指令來參考任何類型
注意
本文是功能規格。 規格可作為功能的設計檔。 其中包含建議的規格變更,以及功能設計和開發期間所需的資訊。 這些文章會發佈,直到提議的規格變更完成並併併入目前的ECMA規格為止。
功能規格與已完成實作之間可能有一些差異。 這些差異是在相關的 語言設計會議(LDM)會議記錄中擷取的。
您可以在描述 規格的一文中深入瞭解將功能規格引入 C# 語言標準的流程。
冠軍問題:https://github.com/dotnet/csharplang/issues/8645
總結
放寬「using_alias_directive」指令(§13.5.2),讓它可以指向任何類型,而不僅限於具名類型。 這支援目前不允許的類型,例如:Tuple 類型、指標類型、陣列類型等。例如,現在允許這樣做:
using Point = (int x, int y);
動機
長期以來,C# 一直能夠為命名空間和具名類型(類別、委派、介面、記錄和結構)引入別名。 在某些情況下,從 using_directive
引入的普通名稱可能會引起歧義,而這個方法可以提供非衝突名稱,並且在處理複雜的泛型類型時,能夠提供一個更簡單的名稱。這使得其運作得當。 不過,語言中其他複雜類型符號的興起,導致出現更多用途,其中別名會很有價值,但目前不允許使用。 例如,元組(tuples)和函式指標通常具有大型且複雜的常規文字形式,這些形式可能會讓持續書寫變得艱難,並且在閱讀時造成負擔。 別名是由開發人員提供的簡短名稱,可以用來替代那些完整的結構形式,從而協助這些情況。
詳細設計
因此,我們將變更 using_alias_directive
的文法:
using_alias_directive
- : 'using' identifier '=' namespace_or_type_name ';'
+ : 'using' identifier '=' (namespace_name | type) ';'
;
不允許最上層參考類型可為 Null 的註釋。
有趣的是,中的大部分規格語言都不需要變更 。13.5.2。 其中大多數的程式語言已經提到 'namespace 或 type',例如:
在立即封入編譯單位或命名空間主體內,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.