Подтвердить что ты не робот

Вложенные пространства имен

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

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

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

using n1;

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

n2.foo smthing;

И как сделать что-то вроде этого возможно?

4b9b3361

Ответ 1

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

using n2 = n1.n2;

...
n2.foo something;

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

Ответ 2

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

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
    }
}

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

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

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

Ответ 3

По дизайну namespaces вы можете определить область видимости.

Если вы полностью не квалифицируете его, вы получите сообщение об ошибке, которое вы видите.

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

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

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

Полностью квалифицированный using

Содержимое File2:

namespace n3
{
    using n1.n2;

    class TestClass
    {
        private Foo something;
    }
}

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

namespace n3
{
    using n2 = n1.n2;

    class TestClass
    {
        private n2.Foo something;
    }
}

Ответ 4

Раздел 9.4.2, пункт 4 в спецификации языка С#, объясняет это поведение явно:

Использование импорта-namespace-import типы, содержащиеся в данном пространства имен, но конкретно не импортировать вложенные пространства имен.

Это еще один пример, который очень похож на ваш.

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 доступен, поскольку он ссылается из блока пространства имен предков.

Ответ 5

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