Добавить в цитаты Настройки чтения

Страница 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>