Пространства имен с областью действия файла
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующих собраниях по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Проблема чемпиона: https://github.com/dotnet/csharplang/issues/137
Сводка
Пространства имен с областью действия файлов используют менее подробный формат для типичного случая файлов, содержащих только одно пространство имен. Формат пространства имен с областью действия файла namespace X.Y.Z;
(обратите внимание на точку с запятой и отсутствие фигурных скобок). Это позволяет использовать такие файлы, как показано ниже.
namespace X.Y.Z;
using System;
class X
{
}
Семантика заключается в том, что использование формы namespace X.Y.Z;
эквивалентно написанию namespace X.Y.Z { ... }
, где оставшаяся часть файла после пространства имен, ограниченного областью действия файла, находится в разделе ...
объявления стандартного пространства имен.
Мотивация
Анализ экосистемы C# показывает, что примерно 99,7% файлы являются одним из следующих форм:
namespace X.Y.Z
{
// usings
// types
}
или
// usings
namespace X.Y.Z
{
// types
}
Однако обе эти формы вынуждают пользователя делать отступы для большей части своего кода и добавлять значительное количество лишних действий для того, что по сути является очень базовой концепцией. Это влияет на ясность, использование горизонтального и вертикального пространства и часто является неудовлетворительным для пользователей, привыкших к C# и приходящих с других языков (где обычно меньше формальностей).
Основная цель этой функции состоит в том, чтобы удовлетворить потребности основной части экосистемы с меньшим количеством ненужного кода.
Подробный дизайн
Это предложение принимает форму диффа к существующим единицам компиляции (§14.2) спецификации.
Дифф
compilation_unit определяет общую структуру исходного файла. Единица компиляции состоит из нуля или более using_directive, затем следует ноль или более global_attributes, затем следует ноль или более namespace_member_declaration.
compilation_unit определяет общую структуру исходного файла. Единица компиляции состоит из нуля или более using_directive, затем нуля или более global_attributes, и затем compilation_unit_body. compilation_unit_body может быть file_scoped_namespace_declaration или нулевым или более оператороми namespace_member_declaration.
compilation_unit
~~ : extern_alias_directive* using_directive* global_attributes? namespace_member_declaration*~~
: extern_alias_directive* using_directive* global_attributes? compilation_unit_body
;
compilation_unit_body
: statement* namespace_member_declaration*
| file_scoped_namespace_declaration
;
... неизменившийся...
file_scoped_namespace_declaration будет определять членов, соответствующих namespace_declaration, которому она семантически эквивалентна. Дополнительные сведения см. в разделе (Объявления пространства имен).
Объявления пространства имен
namespace_declaration состоит из ключевого слова namespace
, за которым следует имя пространства имен и текст, за которым при необходимости следует точка с запятой.
file_scoped_namespace_declaration состоит из ключевого слова namespace
, за которым следует имя пространства имен, точка с запятой и необязательный список extern_alias_directives, using_directives и type_declaration.
namespace_declaration
: 'namespace' qualified_identifier namespace_body ';'?
;
file_scoped_namespace_declaration
: 'namespace' qualified_identifier ';' extern_alias_directive* using_directive* type_declaration*
;
... unchanged ...
... неизменившийся...
Два объявления пространства имен, приведенные выше, относятся к одному и тому же пространству деклараций, в данном случае описывая два класса с полными именами N1.N2.A
и N1.N2.B
. Так как два объявления способствуют одному и тому же пространству объявлений, это было бы ошибкой, если каждая из них содержала объявление члена с одинаковым именем.
file_scoped_namespace_declaration позволяет записывать объявление пространства имен без блока { ... }
. Например:
extern alias A;
namespace Name;
using B;
class C
{
}
является семантически эквивалентным
extern alias A;
namespace Name
{
using B;
class C
{
}
}
В частности, file_scoped_namespace_declaration обрабатывается так же, как namespace_declaration в том же месте в compilation_unit с тем же qualified_identifier. extern_alias_directive, using_directiveи type_declarationэтого file_scoped_namespace_declaration действуют так же, как если бы они были объявлены в том порядке внутри namespace_body этого namespace_declaration.
Исходный файл не может содержать как file_scoped_namespace_declaration, так и namespace_declaration. Исходный файл не может содержать несколько file_scoped_namespace_declarations. compilation_unit не может содержать как file_scoped_namespace_declaration, так и любые инструкции верхнего уровня. type_declarations не может предшествовать file_scoped_namespace_declaration.
Псевдонимы extern (внешние)
... неизменившийся...
C# feature specifications