Столкновения пространства имен - PullRequest
4 голосов
/ 04 ноября 2008

Как это возможно, что .NET находит неправильный 'MyType' в этом сценарии?

У меня есть тип A.B.C.D.MyType в проекте, над которым я работаю, и я ссылаюсь на DLL, которая имеет тип A.B.MyType? У меня нет никакого 'использования A.B;' операторы в любом месте моего кода, и у меня есть «использование A.B.C.D;». Когда я компилирую, компилятор считает, что любая пустая ссылка на «MyType» означает «A.B.MyType».

Я знаю, что могу просто переименовать класс или использовать псевдоним, но мне интересно, как это вообще возможно.

Есть идеи?

Спасибо!

Ответы [ 3 ]

8 голосов
/ 04 ноября 2008

Вы работаете в пространстве имен, которое находится под пространством имен A.B? (например, A.B.X), если это так, разрешения пространства имен C # ( ECMA-334 C # Спецификация языка: 10.8 10.8 Имена пространств имен и типов ) гласят:

... для каждого пространства имен N, начиная с пространством имен, в котором происходит namespace-or-typename, продолжая с каждым вложением пространство имен (если есть) и заканчивается глобальное пространство имен, следующее шаги оцениваются до тех пор, пока расположенный ...

, а затем:

Если K равно нулю и пространство имен декларация содержит директива внешнего псевдонима или using-aliasdirective, который связывает имя я с импортированным пространством имен или введите, то namespace-or-type-name относится к этому пространство имен или тип

Это означает, что разрешение имен начинается с текущего пространства имен и выполняет поиск во всех пространствах имен вплоть до корня, и только после завершения этого иерархического поиска производится поиск в пространствах имен, импортированных с предложением using.

В следующем примере выводится «Ns1.Foo»

using Ns1.Foo.Foo2;

namespace Ns1.Foo
{
    class Foo
    {
        public void Print()
        {
            System.Console.WriteLine("Ns1.Foo");
        }
    }
}

namespace Ns1.Foo.Foo2
{
    class Foo
    {
        public void Print()
        {
            System.Console.WriteLine("Ns1.Foo.Foo2");
        }
    }
}

namespace Ns1.Foo.Bar
{
    class Bar
    {
        public void Print()
        {
            new Foo().Print();
        }

        static void Main()
        {
            new Bar().Print();
        }
    }
}

Редактировать: Добавление предложения using внутри пространства имен приведет к тому, что пространство имен будет найдено до того, как будет выполнен иерархический поиск текущего пространства имен. Измените пример на:

namespace Ns1.Foo.Bar
{
    using Ns1.Foo.Foo2;
    class Bar
    {
        public void Print()
        {
            new Foo().Print();
        }

        static void Main()
        {
            new Bar().Print();
        }
    }
}

и Ns1.Foo.Foo2 будут напечатаны.

Редактировать: измененный пример

3 голосов
/ 04 ноября 2008

Ваш код находится в пространстве имен A.B или A.B.C? Если так, то это, вероятно, проблема. Используйте директиву using так:

using TheTypeIWant = A.B.C.D.MyType;

, тогда просто обратитесь к TheTypeIWant в вашем коде.

РЕДАКТИРОВАТЬ: я только что попробовал вариант "using MyType=A.B.C.D.MyType", но это не работает. Выше все хорошо, хотя.

0 голосов
/ 04 ноября 2008

Просто предположение: в свойствах вашего проекта для "пространства имен по умолчанию" установлено значение A.B?

...