Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время дизайна и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующих совещаниях по разработке языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Вопрос чемпиона: https://github.com/dotnet/csharplang/issues/3428
Синтаксис директивы using расширен с помощью необязательного ключевого слова global, которое может предшествовать ключевому слову using:
compilation_unit
: extern_alias_directive* global_using_directive* using_directive* global_attributes? namespace_member_declaration*
;
global_using_directive
: global_using_alias_directive
| global_using_namespace_directive
| global_using_static_directive
;
global_using_alias_directive
: 'global' 'using' identifier '=' namespace_or_type_name ';'
;
global_using_namespace_directive
: 'global' 'using' namespace_name ';'
;
global_using_static_directive
: 'global' 'using' 'static' type_name ';'
;
- global_using_directiveразрешены только на уровне единицы компиляции (нельзя использовать внутри namespace_declaration).
- global_using_directives, если таковые имеются, должны предшествовать любым using_directive.
- Область действия global_using_directiveраспространяется на namespace_member_declarationвсех единиц компиляции в программе. Область применения global_using_directive в частности не включает другие global_using_directive. Таким образом, одноранговые global_using_directiveили аналогичные из другой единицы компиляции не влияют друг на друга, а порядок, в котором они записаны, не имеет значения. Область действия global_using_directive в частности не включает using_directiveсразу же, содержащихся в любой единице компиляции программы.
Эффект добавления global_using_directive в программу можно рассматривать как эффект добавления аналогичной using_directive, которая разрешается к тому же целевому пространству имен или типу в каждую единицу компиляции программы. Однако целевая директива global_using_directive разрешается в контексте единицы компиляции, содержащей её.
области §7.7
Это соответствующие пункты маркера с предлагаемыми дополнениями (которые полужирным шрифтом):
- Область видимости имени, определяемая extern_alias_directive, охватывает global_using_directives,using_directives, global_attributes и namespace_member_declarationв его непосредственном блоке компиляции или теле пространства имен. extern_alias_directive не вносит новых членов в базовое пространство объявлений. Другими словами, extern_alias_directive не является транзитивным, но, скорее, влияет только на модуль компиляции или тело пространства имен, в котором она происходит.
- Область действия имени, заданного или импортированного с помощью global_using_directive, распространяется на global_attributes и namespace_member_declarationво всех compilation_unitпрограммы.
§7.8 пространства имен и имен типов
В алгоритм, определяющий значение namespace_or_type_name, вносятся изменения следующим образом.
Это соответствующий пункт списка с предлагаемыми дополнениями (которые выделенные жирным шрифтом):
- Если namespace_or_type_name имеет форму
Iили имеет формуI<A1, ..., Ak>:- Если
Kравно нулю, а namespace_or_type_name отображается в объявлении универсального метода (§15.6) и если это объявление включает параметр типа (§15.2.3) с именемI, то namespace_or_type_name ссылается на этот параметр типа. - В противном случае, если namespace_or_type_name встречается в объявлении типа, то для каждого типа экземпляра
T(§15.3.2), начиная с типа экземпляра этого объявления и продолжая с типом экземпляра каждого окружающего класса или структуры (если таковой имеется):- Если
Kравно нулю, а объявлениеTвключает параметр типа с именемI, то namespace_or_type_name ссылается на этот параметр типа. - В противном случае, если namespace_or_type_name появляется в теле объявления типа, и
Tили любой из его базовых типов содержит вложенный доступный тип с именемIи параметрами типаK, то namespace_or_type_name относится к этому типу, построенному с заданными аргументами типа. Если существует несколько таких типов, выбирается тип, объявленный в более производном типе. Обратите внимание, что элементы без типов (константы, поля, методы, свойства, индексаторы, операторы, конструкторы экземпляров, деструкторы и статические конструкторы) и элементы типов с другим числом параметров типа игнорируются при определении значения namespace_or_type_name.
- Если
- Если предыдущие шаги были неудачными, для каждого пространства имен
N, начиная с пространства имен, в котором находится namespace_or_type_name, продолжая с каждым вложенным пространством имен (если есть), и заканчивая глобальным пространством имен, следующие шаги выполняются до тех пор, пока не будет найдена сущность:- Если
Kравно нулю, аI— имя пространства имен вN, то:- Если расположение, в котором происходит namespace_or_type_name, заключено объявлением пространства имен для
N, а объявление пространства имен содержит extern_alias_directive или using_alias_directive, которое связывает имяIс пространством имен или типом, или любым объявлением пространства имен дляNв программе содержит global_using_alias_directive, которая связывает имяIс пространством имен или типом, затем namespace_or_type_name неоднозначно и возникает ошибка во время компиляции. - В противном случае namespace_or_type_name ссылается на пространство имен с именем
IвN.
- Если расположение, в котором происходит namespace_or_type_name, заключено объявлением пространства имен для
- В противном случае, если
Nсодержит доступный тип с именемIи параметрами типаK, то:- Если
Kравно нулю, а расположение, в котором происходит namespace_or_type_name, заключено объявлением пространства имен дляN, а объявление пространства имен содержит extern_alias_directive или using_alias_directive, которое связывает имяIс пространством имен или типом, или объявлением пространства имен дляNв программе содержит global_using_alias_directive, который связывает имяIс пространство имен или тип, тогда namespace_or_type_name неоднозначно и возникает ошибка во время компиляции. - В противном случае namespace_or_type_name ссылается на тип, созданный с заданными аргументами типа.
- Если
- В противном случае, если место, в котором встречается namespace_or_type_name, находится внутри объявления пространства имен для
N:- Если
Kравно нулю, а объявление пространства имен содержит extern_alias_directive или using_alias_directive, которое связывает имяIс импортированным пространством имен или типом, или любое объявление пространства имен дляNв программе содержит global_using_alias_directive, которая связывает имяIс импортированным пространством имен или типом, затем namespace_or_type_name ссылается на это пространство имен или тип. - В противном случае, если пространства имен и объявления типов, импортируемые директивами using_namespace_directiveи using_alias_directiveвнутри объявления пространства имен , а также пространства имен и объявления типов, импортируемые директивами global_using_namespace_directiveи global_using_static_directiveиз любого объявления пространства имен для
Nв программе, содержат ровно один доступный тип с именемIиKпараметрами типа, то namespace_or_type_name ссылается на этот тип, созданный с заданными аргументами типа. - В противном случае, если пространства имен и объявления типов, импортированные директивами using_namespace_directiveи using_alias_directiveв объявлении пространства имен , а также пространствами имен и объявлениями типов, импортированными директивами global_using_namespace_directiveи global_using_static_directiveлюбого объявления пространства имен для
Nв программе, содержат более одного доступного типа с именемIи параметрами типаK, то namespace_or_type_name является неоднозначным, и возникает ошибка.
- Если
- Если
- В противном случае namespace_or_type_name не определен и возникает ошибка во время компиляции.
- Если
Простые имена §12.8.4
Изменения вносятся в правила оценки simple_name следующим образом.
Это соответствующий пункт списка с предлагаемыми дополнениями (которые выделенные жирным шрифтом):
- В противном случае, для каждого пространства имен
N, начиная с пространства имен, в котором встречается simple_name, продолжая с каждым внешним пространством имен (если таковое имеется) и заканчивая глобальным пространством имен, следующие шаги выполняются до тех пор, пока не будет найдена сущность:- Если
Kравно нулю, аI— имя пространства имен вN, то:- Если расположение, в котором происходит simple_name, заключено объявлением пространства имен для
N, а объявление пространства имен содержит extern_alias_directive или using_alias_directive, которое связывает имяIс пространством имен или типом, или любое объявление пространства имен дляNв программе содержит global_using_alias_directive, которое связывает имяIс пространством имен или типом, то simple_name является неоднозначным, и возникает ошибка компиляции. - В противном случае simple_name ссылается на пространство имен под названием
IвN.
- Если расположение, в котором происходит simple_name, заключено объявлением пространства имен для
- В противном случае, если
Nсодержит доступный тип с именемIи параметрами типаK, то:- Если
Kравно нулю, а расположение, в котором происходит simple_name, заключено объявлением пространства имен дляN, а объявление пространства имен содержит extern_alias_directive или using_alias_directive, которое связывает имяIс пространством имен или типом, или любое объявление пространства имен дляNв программе содержит global_using_alias_directive, которая связывает имяIс пространством имен или тип, затем simple_name неоднозначно и возникает ошибка во время компиляции. - В противном случае namespace_or_type_name ссылается на тип, созданный с заданными аргументами типа.
- Если
- В противном случае, если simple_name прописывается в области действия пространства имен для
N:- Если
Kравно нулю, а объявление пространства имен содержит extern_alias_directive или using_alias_directive, которое связывает имяIс импортированным пространством имен или типом, или любое объявление пространства имен дляNв программе содержит global_using_alias_directive, которая связывает имяIс импортированным пространством имен или типом, затем simple_name ссылается на это пространство имен или тип. - В противном случае, если пространства имен и объявления типов импортируются с помощью using_namespace_directiveи using_static_directiveв объявлении пространства имен , а также пространства имен и объявления типов, импортируемые с помощью global_using_namespace_directiveи global_using_static_directiveлюбого объявления пространства имен для
Nв программе, содержат ровно один доступный тип или нерасширяемый статический член с именемIи параметрами типаK, то simple_name ссылается на этот тип или член, созданный с заданными аргументами типа. - В противном случае, если пространства имен и типы, импортированные using_namespace_directiveобъявления пространства имен , а также пространства имен и объявления типов, импортированные global_using_namespace_directiveи global_using_static_directiveлюбого объявления пространства имен для
Nв программе, содержат более чем один доступный тип или статического члена, не являющегося методом расширения, с именемIи параметрами типаK, то simple_name является неоднозначным, и возникает ошибка.
- Если
- Если
Вызовы метода расширения §12.8.10.3
В алгоритм вносятся изменения, чтобы следующим образом найти наилучшую type_nameC.
Это соответствующий пункт списка с предлагаемыми дополнениями (которые выделенные жирным шрифтом):
- Начиная с ближайшего объявления пространства имен, последовательно проходя через каждое включающее пространство имен и завершая поиски в содержащем блоке компиляции, делаются последовательные попытки найти набор методов расширения.
- Если заданное пространство имен или единица компиляции напрямую содержит объявления не универсальных типов
Ciс соответствующими методами расширенияMj, то набор этих методов расширения является набором кандидатов. - Если типы
Ciимпортированы с помощью using_static_declarations и непосредственно объявлены в пространствах имен, импортируемых с помощью using_namespace_directiveв заданном пространстве имен или в единице компиляции , и если достигается при использовании global_using_static_declarations и непосредственно объявленных в пространствах имен, импортируемых с помощью global_using_namespace_directiveв программе, непосредственно содержат допустимые методы расширенияMj, то набор этих методов расширения является набором кандидатов.
- Если заданное пространство имен или единица компиляции напрямую содержит объявления не универсальных типов
Единицы компиляции §14.2
compilation_unit определяет общую структуру исходного файла. Единица компиляции состоит из ноль или более global_using_directiveс ноль или более using_directive, за которым следует ноль или более global_attributes, за которым следует ноль или более namespace_member_declarations.
compilation_unit
: extern_alias_directive* global_using_directive* using_directive* global_attributes? namespace_member_declaration*
;
Программа C# состоит из одного или нескольких единиц компиляции, каждый из которых содержится в отдельном исходном файле. При компиляции программы C# все единицы компиляции обрабатываются вместе. Таким образом, единицы компиляции могут зависеть друг от друга, возможно, в циклической форме.
global_using_directiveединицы компиляции влияют на global_attributes и namespace_member_declarationвсех единиц компиляции в программе.
Псевдонимы extern §14.4
Область extern_alias_directive распространяется на global_using_directive,using_directive, global_attributes и namespace_member_declarationв пределах его непосредственного компиляционного блока или тела пространства имен.
Использование директив псевдонима §14.5.2
Порядок записи using_alias_directiveне имеет значения, а разрешение namespace_or_type_name, на которое ссылается using_alias_directive, не влияет на сам using_alias_directive или другие using_directiveв немедленном тексте единицы компиляции или пространства имен. и, если using_alias_directive немедленно содержится в единице компиляции, не затрагивается global_using_directiveв программе. Иными словами, namespace_or_type_nameusing_alias_directive разрешается как будто непосредственно содержащий модуль компиляции или тело пространства имен не содержало using_directive, и, если using_alias_directive непосредственно содержится в единице компиляции, программа не имела global_using_directive. Однако на using_alias_directive могут повлиять extern_alias_directiveв непосредственном блоке компиляции или тексте пространства имен.
Директивы глобального использования псевдонимов
global_using_alias_directive вводит идентификатор, который служит в качестве псевдонима для пространства имен или типа в программе.
global_using_alias_directive
: 'global' 'using' identifier '=' namespace_or_type_name ';'
;
В объявлениях членов в любой единице компиляции программы, содержащей global_using_alias_directive, идентификатор, представленный global_using_alias_directive, можно использовать для ссылки на заданное пространство имен или тип.
Идентификатор директивы global_using_alias_directive должен быть уникальным в пределах пространства объявлений любой единицы компиляции программы, содержащей директиву global_using_alias_directive.
Как и обычные члены, имена, представленные global_using_alias_directive, скрыты аналогично именованными элементами во вложенных областях.
Порядок, в котором записываются global_using_alias_directive, не имеет значения, и разрешение namespace_or_type_name, на которое ссылается global_using_alias_directive, не зависит ни от самого global_using_alias_directive, ни от других global_using_directiveили using_directiveв программе. Иными словами, namespace_or_type_nameglobal_using_alias_directive разрешается так, как если бы непосредственно содержащий модуль компиляции был без using_directives, а вся содержащая программа была без global_using_directives. Однако на global_using_alias_directive могут повлиять extern_alias_directiveв непосредственном блоке компиляции.
global_using_alias_directive может создать псевдоним для любого пространства имен или типа.
Доступ к пространству имен или типу с помощью псевдонима дает точно тот же результат, что и доступ к пространству имен или типу через объявленное имя.
Используя псевдонимы, можно обозначить закрытый конструированный тип, но нельзя обозначить объявление обобщенного типа без указания аргументов типа.
Глобальные директивы пространства имен
global_using_namespace_directive импортирует типы из пространства имен в программу, позволяя использовать идентификатор каждого типа без необходимости указания квалификации.
global_using_namespace_directive
: 'global' 'using' namespace_name ';'
;
В объявлениях членов в программе, содержащей global_using_namespace_directive, можно ссылаться непосредственно на типы, содержащиеся в заданном пространстве имен.
global_using_namespace_directive импортирует типы, содержащиеся в заданном пространстве имен, но в частности не импортирует вложенные пространства имен.
В отличие от global_using_alias_directive, global_using_namespace_directive может импортировать типы, идентификаторы которых уже определены в единице компиляции программы. Фактически, в заданной единице компиляции имена, импортированные любым global_using_namespace_directive в программе, скрыты аналогично именованными элементами в единице компиляции.
Если несколько пространств имен или типов, импортированных global_using_namespace_directiveили global_using_static_directiveв одной программе, содержат типы по одному type_name имени, ссылки на это имя считаются неоднозначными.
Кроме того, если несколько пространств имен или типов, импортированных global_using_namespace_directiveили global_using_static_directiveв той же программе, содержат типы или члены с одинаковыми именами, ссылки на это имя как simple_name считаются неоднозначными.
namespace_name, на который ссылается global_using_namespace_directive, определяется тем же образом, что и namespace_or_type_name, на который ссылается global_using_alias_directive. Таким образом, global_using_namespace_directiveв одной программе не влияют друг на друга и могут быть записаны в любом порядке.
Глобальное использование статических директив
global_using_static_directive импортирует вложенные типы и статические члены, содержащиеся непосредственно в объявлении типа, в содержащую программу, что позволяет использовать идентификатор каждого члена и типа без квалификации.
global_using_static_directive
: 'global' 'using' 'static' type_name ';'
;
В объявлениях членов программы, содержащей global_using_static_directive, можно использовать напрямую доступные вложенные типы и статические члены (кроме методов расширения), содержащиеся непосредственно в объявлении данного типа.
global_using_static_directive специально не импортирует методы расширения непосредственно как статические методы, но делает их доступными для вызова метода расширения.
global_using_static_directive импортирует только элементы и типы, объявленные непосредственно в данном типе, а не члены и типы, объявленные в базовых классах.
Неоднозначность между несколькими global_using_namespace_directiveи global_using_static_directives рассматриваются в разделе global_using_namespace_directive(выше).
Квалифицированный участник псевдонима §14.8
В алгоритм, определяющий значение qualified_alias_member, вносятся изменения следующим образом.
Это соответствующий пункт списка с предлагаемыми дополнениями (которые выделенные жирным шрифтом):
В противном случае, начиная с объявления пространства имен (§14.3), непосредственно содержащего qualified_alias_member (если он существует), затем охватывая каждое следующее объявление пространства имен (если они существуют) и заканчивая единицей компиляции, содержащей qualified_alias_member, оцениваются следующие шаги до тех пор, пока не будет найдена сущность:
- Если объявление пространства имен или единица компиляции содержит using_alias_directive, которая связывает
Nс типом, или когда достигается единица компиляции, программа содержит global_using_alias_directive, которая связываетNс типом, не определена qualified_alias_member и возникает ошибка во время компиляции. - В противном случае, если объявление пространства имен или единица компиляции содержит extern_alias_directive или using_alias_directive, которая связывает
Nс пространством имен, *или при достижении единицы компиляции программа содержит global_using_alias_directive, которая связываетNс пространством имен, затем:- Если пространство имен, связанное с
N, содержит пространство имен с именемIиKравно нулю, то qualified_alias_member ссылается на это пространство имен. - В противном случае, если пространство имен, связанное с
N, содержит не универсальный тип с именемIиKравно нулю, то qualified_alias_member ссылается на этот тип. - В противном случае, если пространство имен, связанное с
N, содержит тип с именемIс параметрами типаK, то qualified_alias_member ссылается на этот тип, созданный с заданными аргументами типа. - В противном случае qualified_alias_member не определен и возникает ошибка во время компиляции.
- Если пространство имен, связанное с
- Если объявление пространства имен или единица компиляции содержит using_alias_directive, которая связывает
C# feature specifications