Вложенные пространства имен - PullRequest
29 голосов
/ 09 июня 2011

У меня есть что-то вроде этого:

namespace n1
{
    namespace n2
    {
        class foo{}
    }
}

В другом файле я пишу:

using n1;

Почему я не могу сейчас напечатать что-то вроде:

n2.foo smthing;

А как сделать что-то подобное этой возможности?

Ответы [ 5 ]

31 голосов
/ 09 июня 2011

Это преднамеренное правило C #. Если вы сделаете это:

namespace Frobozz
{
    namespace Magic
    {
        class Lamp {}
    }

    class Foo
    {
        Magic.Lamp myLamp; // Legal; Magic means Frobozz.Magic when inside Frobozz
    }
}

Это законно. Но это не так:

namespace Frobozz
{
    namespace Magic
    {
        class Lamp {}
    }
}

namespace Flathead
{
    using Frobozz;
    class Bar
    {
        Magic.Lamp myLamp; // Illegal; merely using Frobozz does not bring Magic into scope
    }
}

Правило C #, которое описывает это, приведено в разделе 7.6.2 спецификации C # 4. Это очень запутанный раздел; бит, который вы хотите, это абзац в конце, который говорит

В противном случае, если пространства имен, импортированные директивами using-namespace декларации пространства имен, содержат ровно один тип с именем I ...

Ключевым моментом является то, что в нем говорится «ровно один тип», а не «ровно один тип или пространство имен ». Мы сознательно не разрешаем вам «нарезать» имя пространства имен, например , когда вы находитесь за пределами этого пространства имен , поскольку это может привести к путанице. Как уже говорили другие, если вы хотите делать подобные вещи, полностью уточните это один раз в директиве using-alias, а затем используйте псевдоним.

26 голосов
/ 09 июня 2011

Использовать псевдонимы пространства имен :

using n2 = n1.n2;

...
n2.foo something;

То, что находится перед именем класса, должно представлять собой полное пространство имен (с / или другими именами классов для вложенных типов). Усеченное пространство имен не будет работать.

11 голосов
/ 09 июня 2011

По определению, namespaces помогут вам определить область.

Если вы не полностью ее укажете, вы получите сообщение об ошибке.

Предполагая, что File1 имеет что-то вроде этого:

namespace n1
{
    namespace n2
    {
        class Foo { }
    }
}

Вы можете сделать это двумя способами:

Полная квалификация using

Содержимое файла 2:

namespace n3
{
    using n1.n2;

    class TestClass
    {
        private Foo something;
    }
}

Используйте namespace alias

namespace n3
{
    using n2 = n1.n2;

    class TestClass
    {
        private n2.Foo something;
    }
}
8 голосов
/ 09 июня 2011

В параграфе 4 раздела 9.4.2 спецификации языка C # это поведение объясняется в явном виде:

A using-namespace-directive импортирует типы, содержащиеся в данном пространстве имен, нов частности, не импортирует вложенные пространства имен.

Далее приводится даже пример, очень похожий на ваш.

namespace N1.N2
{
    class A {}
}
namespace N3
{
    using N1;
    class B: N2.A {}        // Error, N2 unknown
}

Конечно, если бы вы сделали это:

namespace n1
{
  public class Example
  {
    public static void Main()
    {
      n2.Foo a; // This is legal.
    }
  }
}

Это скомпилируется, потому что n2 доступен, так как на него ссылаются из блока пространства имен предка.

0 голосов
/ 01 октября 2015

Вы не можете написать это, так как n2 находится внутри n1.Если вы хотите получить доступ к пространству имен n2, попробуйте ввести using n2 = n1.n2 в начале вашего другого файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...