C# где должны находиться директивы using?


#1

Немного почитал о StyleCop и решил проверить свой код на соответствие его рекомендациям. Так вот он мне постоянно выдаёт сообщение, что директивы using должны находится внутри пространства имён. Я не могу понять, по каким причинам их нужно переместить внутрь пространства имён? Ведь даже при создании консольного проекта по шаблону, они находятся вне пространства имён.


#2

есть "тонкая" разница между помещением директив using в пространстве имён и за ним. Лучше всего рассмотреть её на следующем примере:
у нас есть два файла с кодом на c#

код первого файла:

using System;

namespace Outer.Inner
{
    class Foo
    {
        static void MyPow()
        {
            double d = Math.Pow(2, 10);
        }
    }
}

код второго файла:

namespace Outer
{
    class Math
    {

    }
}

оба эти файла находятся в одном проекте, поэтому в первую очередь компилятор будет искать Outer перед тем как смотреть на подключенные библиотеки, что в свою очередь приведёт к нахождению класса Math в пространстве имён Outer, а не в пространстве имён System. Таким образом Math.Pow(2, 10) будет пытаться вызвать несуществующий метод из класса Outer.Math, что приведёт к ошибке.

Если же поместить директиву using внутрь пространства имён:

namespace Outer.Inner
{
    using System;

    class Foo
    {
        static void MyPow()
        {
            double d = Math.Pow(2, 10);
        }
    }
}

, то изначально компилятор найдёт System.Math, а потом уже Outer.Math. Поэтому программа будет работать правильно.

Конечно же использования Math в качестве имени пользовательского класса может произойти достаточно редко, но сама суть этого не привязывается к имени, а говорит о том, что пользователь может создать свой собственный класс использовав имя уже существующего типа в подключенном пространстве имён, что может привести к ошибке.

Также интересно отметить, что происходит, если Foo находится в пространстве имен Outer, а не Outer.Inner. В этом случае добавление Outer.Math во второй файл нарушит работу первого файла независимо от того, где находится using. Это подразумевает, что компилятор ищет самое внутреннее пространство имен, прежде чем он смотрит на любую директиву using.


#3

спасибо!