Страница 245 из 502
<b>}</b>
<b>class NestedNSDemo {</b>
<b> static void Main() {</b>
<b> NS1.ClassA a = new NS1.ClassA();</b>
<b> // NS2.ClassB </b><b>b = new NS2.ClassB(); // Неверно!!! Пространство NS2 невидимо</b>
<b> NS1.NS2.ClassB b = new NS1.NS2.ClassB(); // Верно!</b>
<b> }</b>
<b>}</b>
Выполнение этой программы дает следующий результат.
<b>Конструирование класса ClassA </b>
<b>Конструирование класса ClassB</b>
В этой программе пространство имен NS2 вложено в пространство имен NS1. Поэтому для обращения к классу ClassB необходимо дополнительно указать пространства имен NS1 и NS2. Указания одного лишь пространства имен NS2 для этого недостаточно. Как следует из приведенного выше примера, пространства имен дополнительно указываются через точку. Следовательно, для обращения к классу ClassB в методе Main() необходимо указать его полное имя — NSl.NS2.ClassB.
Пространства имен могут быть вложенными больше, чем на два уровня. В этом случае член вложенного пространства имен должен быть дополнительно определен с помощью всех охватывающих пространств имен.
Вложенные пространства имен можно указать в одном операторе namespace, разделив их точкой. Например, вложенные пространства имен
<b>namespace OuterNS { namespace I
<b> // ...</b>
<b> }</b>
<b>}</b>
могут быть указаны следующим образом.
<b>namespace OuterNS.I
<b>// ...</b>
<b>}</b>
Если в программе не объявлено пространство имен, то по умолчанию используется глобальное пространство имен. Именно поэтому в примерах программ, представленных в предыдущих главах книги, не нужно было обращаться для этой цели к ключевому слову namespace. Глобальное пространство удобно для коротких программ, как в примерах из этой книги, но в большинстве случаев реальный код содержится в объявляемом пространстве имен. Главная причина инкапсуляции кода в объявляемом пространстве имен — предотвращение конфликтов имен. Пространства имен служат дополнительным средством, помогающим улучшить организацию программ и приспособить их к работе в сложной среде с современной сетевой структурой.
Пространства имен помогают предотвратить конфликты имен, но не устранить их полностью. Такой конфликт может, в частности, произойти, когда одно и то же имя объявляется в двух разных пространствах имен и затем предпринимается попытка сделать видимыми оба пространства. Допустим, что два пространства имен содержат класс MyClass. Если попытаться сделать видимыми оба пространства имен с помощью директив using, то имя MyClass из первого пространства вступит в конфликт с именем MyClass из второго пространства, обусловив появление ошибки неоднозначности. В таком случае для указания предполагаемого пространства имен явным образом можно воспользоваться описателем псевдонима пространства имен <i>::</i>.
Ниже приведена общая форма оператора ::.
<b>псевдоним_пространства_имен :: идентификатор</b>
Здесь псевдоним_пространства_имен обозначает конкретное имя псевдонима пространства имен, а идентификатор — имя члена этого пространства.
Для того чтобы стало понятнее назначение описателя псевдонима пространства имен, рассмотрим следующий пример программы, в которой создаются два пространства имен, Counter и AnotherCounter, и в обоих пространствах объявляется класс CountDown. Затем оба пространства имен становятся видимыми с помощью директив using. И наконец, в методе Main() предпринимается попытка получить экземпляр объекта типа CountDown.
<b>// Продемонстрировать необходимость описателя ::.</b>
<b>using System;</b>
<b>// Использовать оба пространства имен Counter и AnotherCounter.</b>
<b>using Counter;</b>
<b>using AnotherCounter;</b>
<b>// Объявить пространство имен для счетчиков,</b>
<b>namespace Counter {</b>
<b> // Простой вычитающий счетчик,</b>
<b> class CountDown {</b>
<b> int val;</b>
<b> public CountDown(int n) {</b>
<b> val = n;</b>
<b> }</b>
<b> // ...</b>
<b> }</b>
<b>}</b>
<b>// Объявить еще одно пространство имен для счетчиков,</b>
<b>namespace AnotherCounter {</b>
<b> // Объявить еще один класс CountDown, принадлежащий </b>
<b> // пространству имен AnotherCounter.</b>
<b> class CountDown {</b>
<b> int val;</b>
<b> public CountDown(int n) {</b>