Sdílet prostřednictvím


Povolit použití direktivy alias pro odkazování na jakýkoli druh typu

Poznámka

Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.

Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v příslušných poznámkách ze schůzky pro návrh jazyka (LDM) .

Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .

Problém čempiona: https://github.com/dotnet/csharplang/issues/8645

Shrnutí

Uvolněte using_alias_directive (§13.5.2), aby mohl odkazovat na jakýkoli typ, ne jen pojmenované typy. To by podporovalo typy, které dnes nejsou povoleny, například: typy n-tic, typy ukazatelů, typy polí atd.; toto by teď bylo například povoleno:

using Point = (int x, int y);

Motivace

Po dlouhou dobu měl jazyk C# schopnost zavádět aliasy pro obory názvů a pojmenované typy (třídy, delegáty, rozhraní, záznamy a struktury). To fungovalo přijatelně dobře, protože poskytovalo způsob, jak zavést nekonfliktní názvy v případech, kdy by normální názvy vytažené z using_directivemohly být nejednoznačné, a umožnilo poskytnout jednodušší název při práci se složitými generickými typy. Nárůst dalších komplexních symbolů typů v jazyce však vedl k většímu použití tam, kde by aliasy byly cenné, ale momentálně nejsou povoleny. Například n-tice i ukazatele na funkci můžou mít často velké a složité pravidelné textové formy, které můžou být bolestné při trvalém psaní a zátěží při snaze přečíst. Aliasy by v těchto případech pomohly poskytnutím krátkého názvu poskytnutého vývojářem, který pak lze použít místo těchto úplných strukturních formulářů.

Podrobný návrh

Gramatiku using_alias_directive změníme takto:

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

Poznámky k nullable typům na nejvyšší úrovni jsou zakázány.

Zajímavé je, že většina specifického jazyka v §13.5.2 se nemusí měnit. Většina jazyka v něm již odkazuje na obor názvů nebo typ, například:

Direktiva using_alias zavádí identifikátor, který slouží jako alias pro obor názvů nebo typ v rámci bezprostředně obklopující kompilační jednotky nebo těla oboru názvů.

To zůstává pravdou, pouze že gramatika teď umožňuje „typ“ být jakýkoliv typ, na rozdíl od omezené sady dříve povolené pro namespace_or_type_name.

Oddíly, které potřebují aktualizaci, jsou:

- 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.

Podpůrné aliasy pro typy obsahující ukazatele

Nový unsafe kontext se přidává prostřednictvím volitelného klíčového slova 'unsafe' v produkci using_alias_directive:

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.