Zezwalaj na używanie dyrektywy aliasu w celu odwołowania się do dowolnego rodzaju typu
Notatka
Ten artykuł jest specyfikacją funkcji. Specyfikacja służy jako dokument projektowy dla funkcji. Zawiera proponowane zmiany specyfikacji wraz z informacjami wymaganymi podczas projektowania i opracowywania funkcji. Te artykuły są publikowane do momentu sfinalizowania proponowanych zmian specyfikacji i włączenia ich do obecnej specyfikacji ECMA.
Mogą wystąpić pewne rozbieżności między specyfikacją funkcji a ukończoną implementacją. Te różnice są odnotowane w odpowiednich notatkach ze spotkań projektowych dotyczących języka (LDM) .
Więcej informacji na temat procesu wdrażania specyfikacji funkcji można znaleźć w standardzie języka C# w artykule dotyczącym specyfikacji .
Problem z mistrzem: https://github.com/dotnet/csharplang/issues/8645
Streszczenie
Rozluźnij dyrektywę using_alias (§13.5.2), aby umożliwić jej wskazywanie na dowolny rodzaj typu, a nie tylko typy nazwane. Obsługiwałoby to typy niedozwolone dzisiaj, jak: krotki, typy wskaźnikowe, typy tablic itp. Na przykład, byłoby to teraz dozwolone:
using Point = (int x, int y);
Motywacja
Od dawna, C# ma możliwość wprowadzania aliasów dla przestrzeni nazw i nazwanych typów (klas, delegacji, interfejsów, rekordów i struktur). To działało zadowalająco dobrze, ponieważ stanowiło sposób wprowadzenia nazw niepowodujących konfliktów w przypadkach, gdy zwykle używana nazwa pobierana z using_directive
s może być niejednoznaczna, i umożliwiło nadanie prostszej nazwy podczas radzenia sobie ze złożonymi typami ogólnymi. Jednak wzrost dodatkowych, bardziej złożonych symboli typu w języku spowodował pojawienie się więcej sytuacji, gdzie aliasy byłyby cenne, ale obecnie nie są dozwolone. Na przykład zarówno krotki, jak i wskaźniki funkcji często mogą mieć duże i złożone regularne formy tekstowe, których ciągłe zapisywanie może być uciążliwe, oraz trudne do czytania. Aliasy pomogłyby w tych przypadkach, podając krótką, podaną przez deweloperów nazwę, która może być następnie używana zamiast tych pełnych form strukturalnych.
Szczegółowy projekt
W ten sposób zmienimy gramatykę using_alias_directive
:
using_alias_directive
- : 'using' identifier '=' namespace_or_type_name ';'
+ : 'using' identifier '=' (namespace_name | type) ';'
;
Adnotacje na temat nullowalności typu odwołania najwyższego poziomu są niedozwolone.
Co ciekawe, większość języka specyfikacji w §13.5.2 nie musi się zmieniać. Większość języka w nim odwołuje się już do "przestrzeni nazw lub typu", na przykład:
Using_alias_directive wprowadza identyfikator, który służy jako alias dla przestrzeni nazw lub typu w obrębie natychmiast otaczającej jednostki kompilacji lub treści przestrzeni nazw.
Pozostaje to prawdą, z tym że gramatyka teraz pozwala, aby "typ" był dowolnym typem, a nie ograniczonym zestawem dozwolonym wcześniej przez namespace_or_type_name
.
Sekcje, które wymagają aktualizacji, to:
- 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.
Obsługa aliasów dla typów zawierających wskaźniki.
Nowy niebezpieczny kontekst jest dodawany za pomocą opcjonalnego słowa kluczowego "niebezpieczne" w środowisku produkcyjnym 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.
C# feature specifications