Erlauben Sie die Verwendung der Alias-Direktive, um auf jeden beliebigen Typ zu verweisen.
Anmerkung
Dieser Artikel ist eine Featurespezifikation. Die Spezifikation dient als Designdokument für das Feature. Es enthält vorgeschlagene Spezifikationsänderungen sowie Informationen, die während des Entwurfs und der Entwicklung des Features erforderlich sind. Diese Artikel werden veröffentlicht, bis die vorgeschlagenen Spezifikationsänderungen abgeschlossen und in die aktuelle ECMA-Spezifikation aufgenommen werden.
Es kann einige Abweichungen zwischen der Featurespezifikation und der abgeschlossenen Implementierung geben. Diese Unterschiede werden in den entsprechenden Hinweisen zum Language Design Meeting (LDM) erfasst.
Weitere Informationen zum Einführen von Featurespezifikationen in den C#-Sprachstandard finden Sie im Artikel zu den Spezifikationen.
Champion Issue: https://github.com/dotnet/csharplang/issues/8645
Zusammenfassung
Lockern Sie die using_alias_directive (§13.5.2), um ihr die Möglichkeit zu bieten, auf jede Art von Typ zu zeigen, nicht nur auf benannte Typen. Dies würde typen unterstützen, die heute nicht zulässig sind, z. B. Tupeltypen, Zeigertypen, Arraytypen usw. Dies wäre z. B. jetzt zulässig:
using Point = (int x, int y);
Motivation
Seit langem kann C# Aliase für Namespaces und benannte Typen (Klassen, Delegaten, Schnittstellen, Datensätze und Strukturen) einführen. Dies funktionierte akzeptabel gut, da es eine Möglichkeit bot, nicht widersprüchliche Namen in Fällen einzuführen, in denen ein normaler Name, der aus using_directive
importiert wurde, mehrdeutig sein könnte, und es ermöglichte, beim Umgang mit komplexen generischen Typen einen einfacheren Namen bereitzustellen. Die Zunahme zusätzlicher komplexer Typsymbole in der Sprache hat jedoch dazu geführt, dass mehr Verwendung entsteht, wo Aliase nützlich wären, aber derzeit nicht zulässig sind. Sowohl Tupel als auch Funktionszeiger können zum Beispiel oft große und komplexe reguläre Textformen haben, die mühsam auszuschreiben und schwer zu lesen sind. Aliase würden in diesen Fällen helfen, indem sie einen kurzen, vom Entwickler bereitgestellten Namen geben, der dann anstelle dieser vollständigen Strukturformen verwendet werden kann.
Detailentwurf
Wir werden die Grammatik der using_alias_directive
so ändern:
using_alias_directive
- : 'using' identifier '=' namespace_or_type_name ';'
+ : 'using' identifier '=' (namespace_name | type) ';'
;
Anmerkungen zur Nullierbarkeit des Referenztyps auf oberster Ebene sind unzulässig.
Interessanterweise müssen sich die meisten der Spezifikationssprache in §13.5.2 nicht ändern. Die meisten Sprachen verweisen darin bereits auf "Namespace oder Typ", zum Beispiel:
Eine using_alias_directive führt einen Bezeichner ein, der als Alias für einen Namespace oder Typ innerhalb der unmittelbar umschließenden Kompilierungseinheit oder dem Body des Namespaces dient.
Dies ist nach wie vor der Fall, nur dass die Grammatik jetzt zulässt, dass der 'Typ' ein beliebiger Typ ist und nicht mehr das begrenzte Set, das durch namespace_or_type_name
festgelegt wurde.
Die Abschnitte, die aktualisiert werden müssen, sind:
- 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.
Unterstützung von Aliasen für Typen, die Zeiger enthalten.
Ein neuer unsicherer Kontext wird durch ein optionales 'unsafe' Schlüsselwort in der using_alias_directive Produktion hinzugefügt:
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.
C# feature specifications