Разрешить использовать директиву псевдонима для ссылки на любой тип.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию 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
s, может быть неоднозначным, и оно позволило предоставить более простое имя при работе с сложными обобщенными типами. Однако появление дополнительных сложных символов в языке привело к большей востребованности, в условиях которой использование псевдонимов было бы ценным, но в настоящее время не допускается. Например, кортежи и указатели функций часто могут иметь большие и сложные обычные текстовые формы, которые сложно постоянно записывать и сложно читать. Псевдонимы помогут в этих случаях, предоставив короткое, предоставленное разработчиком имя, которое затем можно использовать вместо этих полных структурных форм.
Подробный дизайн
Мы изменим грамматику using_alias_directive
таким образом:
using_alias_directive
- : 'using' identifier '=' namespace_or_type_name ';'
+ : 'using' identifier '=' (namespace_name | type) ';'
;
Аннотации ссылочного типа верхнего уровня, разрешающие значение NULL, запрещены.
Интересно, что большая часть языка спецификаций в §13.5.2 не требует изменения. Большинство языков уже содержит ссылки на «пространство имен или тип», например:
В using_alias_directive вводится идентификатор, который служит псевдонимом для пространства имен или типа в пределах непосредственно окружающего блока компиляции или области пространства имен.
Это остается верным, так же, что грамматика теперь позволяет типу быть любым произвольным типом, а не ограниченным набором, разрешенным 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.
Поддержка псевдонимов для типов, содержащих указатели.
Новый небезопасный контекст добавляется с помощью необязательного ключевого слова unsafe в рабочей среде 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