Имена пространств имен и типов
Некоторые контексты в программе на C# требуют указания имени пространства имен или имени типа.
namespace-name:
namespace-or-type-name
type-name:
namespace-or-type-name
namespace-or-type-name:
identifier type-argument-listopt
namespace-or-type-name . identifier type-argument-listopt
qualified-alias-member
Имя пространства имен — это имя пространства имен или типа, ссылающееся на пространства имен. Согласно описанию ниже следующее разрешение имени пространства имен или типа от имени пространства имен должно ссылаться на пространство имен, в противном случае возникает ошибка времени компилирования. Аргументы типов (§4.4.1) не могут быть представлены в имени пространства имен (только типы с аргументами типа).
Имя типа — это имя пространства имен или типа, ссылающееся на тип. Согласно описанию ниже следующее разрешение имени пространства имен или типа от имени типа должно ссылаться на тип, в противном случае возникает ошибка времени компилирования.
Если имя пространства имен или типа является членом квалифицированного псевдонима, его значение соответствует описанию в разделе §9.7. В противном случае имя пространства имен или типа имеет одну из следующих четырех форм.
· I
· I<A1, ..., AK>
· N.I
· N.I<A1, ..., AK>
где I — отдельный идентификатор, N — имя пространства имени или типа и <A1, ..., AK> — дополнительный список аргументов типа. Если список аргументов типа не указан, K считается равным нулю.
Значение имени пространства имен или типа определяется следующим образом.
· Имя пространства имен или типа имеет одну из форм I или форму I<A1, ..., AK>:
o Если K имеет нулевое значение, имя пространства имен или типа появляется в универсальном методе объявления (§10.6), а также если это объявление включает параметр типа (§10.1.3) с именем I, имя пространства имен или типа ссылается на данный параметр типа.
o В противном случае, если имя пространства имен или типа появляется в объявлении типа, то для каждого типа экземпляра T (§10.3.1), начиная с типа экземпляра данного объявления типа и далее для типов экземпляра каждого включающего класса или объявления структуры (при наличии):
· Если K имеет нулевое значение, а объявление T включает параметр типа с именем I, то имя пространства имен или типа ссылается на данный параметр типа.
· В противном случае, если имя пространства имен или типа появляется в теле объявления типа, а T или любой его базовый тип содержит вложенный доступный тип с именем I и параметрами типа K, то имя пространства имен или типа ссылается на этот тип, сформированный с данными аргументами типа. При наличии более одного типа структуры выбирается тип, объявленный в рамках большего производного типа. Обратите внимание, что члены, не являющиеся типами (константы, поля, методы, свойства, индексаторы, операторы, экземпляры, конструкторы, деструкторы и статические конструкторы), и члены типа с различным числом параметров типа игнорируются при определении значения имени пространства имен или типа.
o Если предыдущие шаги не были успешно выполнены, для каждого пространства имен N, начиная с пространства имен, содержащего имя пространства имен или типа, далее для каждого включающего пространства имен (при наличии), и заканчивая глобальным пространством имен, вычисляются следующие шаги до нахождения сущности.
· Если K равно нулю и I является именем пространства имен в N, то:
o Если местоположение, содержащее имя пространства имен или типа, заключено объявлением пространства имен для N, а объявление пространства имен содержит директиву extern alias или директиву using-alias, связывающую имя I с пространством имен или типом, то имя пространства имен или типа неоднозначно, поэтому возникает ошибка времени компилирования.
o В противном случае имя пространства имен или типа ссылается на пространство имен с именем I в N.
· Иначе, если N содержит доступный тип с именем I и параметрами типа K, то:
o Если K имеет нулевое значение и местоположение, содержащее имя пространства имен или типа, заключено объявлением пространства имен для N, а объявление пространства имен содержит директиву extern alias или директиву using alias, связывающие имя I с пространством имен или типом, то имя пространства имен или типа неоднозначно, поэтому возникает ошибка времени компилирования.
o Иначе имя пространства имен или типа относится к типу, сформированному с данными аргументами типа.
· Наоборот, местоположение, содержащее имя пространства имен или типа, заключено объявлением пространства имен для N.
o Если K имеет нулевое значение и объявление пространства имен содержит директиву extern alias или директиву using alias, связывающих имя I с импортированным пространством имен или типом, то имя пространства имен или типа ссылается на данное пространство имен или тип.
o В противном случае, если пространства имен, импортированные с помощью директивы using namespace, объявления пространства имен содержат точно один тип с именем I и параметрами типа K, то имя пространства имен или типа ссылается на данный тип, сконструированный с заданными аргументами типа.
o В противном случае, если пространства имен, импортированные с помощью директивы using namespace, объявления пространства имен содержат точно один тип с именем I и параметрами типа K, то имя пространства имен или типа является неоднозначным и возникает ошибка.
o В противном случае имя пространства имен или типа не определено, поэтому возникает ошибка времени компилирования.
· В противном случае имя пространства имен или типа имеет одну из форм N.I или форму N.I<A1, ..., AK>. N впервые разрешается в качестве имени пространства имен или типа. Если разрешение N неуспешно, возникает ошибка времени компилирования. В противном случае N.I или N.I<A1, ..., AK> разрешается следующим образом.
o Если K имеет нулевое значение и N ссылается на пространство имен и N содержит вложенное пространство имен с именем I, то имя пространства имен или типа ссылается на данное вложенное пространство имен.
o В противном случае, если N ссылается на пространство имен и N содержит доступный тип с именем I и параметрами типа K, то имя пространства имен или типа ссылается на данный тип, сконструированный с заданными аргументами типа.
o В противном случае, если N ссылается на тип класса (возможно, сформированного) или тип структуры и если N или любой его базовый класс содержит вложенный доступный тип с именем I и параметрами типа K, то имя пространства имен или типа ссылается на данный тип, сформированный с заданными аргументами типа. При наличии более одного типа структуры выбирается тип, объявленный в рамках большего производного типа. Следует отметить, что если значение N.I определяется как часть разрешения спецификации базового класса N, прямой базовый класс N считается объектом (§10.1.4.1).
o В противном случае N.I является недействительным именем пространства имен или типа, поэтому возникает ошибка времени компилирования.
Ссылка имени пространства имен или типа на статический класс (§10.1.1.3) допускается только в следующих случаях.
· Имя пространства имен или типа T в имени пространства имен или типа формы T.I или
· Имя пространства имен или типа равно T в выражении typeof (§7.5.11) в виде typeof(T).
Полные имена
Каждое пространство имен и тип имеют полные имена, уникально идентифицирующие пространство имен или тип среди других пространств имен и типов. Значение полного имени пространства имен или типа N определяется следующим образом.
· Если N является членом глобального пространства имен, его полное имя N.
· В противном случае его полное имя S.N, где S — полное имя пространства имен или типа, в котором N объявлен.
Другими словами, полное имя N представляет полный иерархический путь идентификаторов, ведущих к N, начиная с глобального пространства имен. Так как каждый член пространства имен или типа должен иметь уникальное имя, полное имя пространства имен или типа всегда уникально.
В следующем примере представлено несколько объявлений пространств имен и типов вместе с соответствующими полными именами.
class A {} // A
namespace X // X
{
class B // X.B
{
class C {} // X.B.C
}
namespace Y // X.Y
{
class D {} // X.Y.D
}
}
namespace X.Y // X.Y
{
class E {} // X.Y.E
}