Объявление пространств имен в c#?

252
14 мая 2017, 21:21

Всем привет. Почему в данном примере:

// Пространства имен.
using NamespaceA;
using NamespaceA.NamespaceB;
using NamespaceA.NamespaceB.NamespaceC;
namespace NamespaceA
{
    namespace NamespaceB
    {
        namespace NamespaceC
        {
            class MyClassC { }
        }
        class MyClassB { }
    }
    class MyClassA { }
}
// В данном месте импорт недопустим.
// Импорт допустим или в теле namespace, или перед всеми другими пространствами имен.
//using NamespaceA;
//using NamespaceA.NamespaceB;
//using NamespaceA.NamespaceB.NamespaceC;
namespace Namespaces
{
    class Program
    {
        static void Main()
        {
            MyClassA myA = new MyClassA();
            MyClassB myB = new MyClassB();
            MyClassC myC = new MyClassC();
        }
    }
}

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

// В данном месте импорт недопустим.

// Импорт допустим или в теле namespace, или перед всеми другими пространствами имен.

Так вот, у меня вопрос к данному правилу. Ведь c# - это компилируемый язык а не интерпретируемый, а значит код не читается строчка за строчкой а строится синтаксическое дерево. И поэтому мне интересно не все ли равно где объявлять пространства имен?

Answer 1

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

Смотрите. Пускай у нас в другом файле есть такие декларации:

namespace A
{
    static class X { static public void Print() { System.Console.WriteLine("I am A::X"); } }
}
namespace B
{
    static class X { static public void Print() { System.Console.WriteLine("I am B::X"); } }
}

Заведём чистый файл, и в него поместим такую вот программу:

namespace A.Z
{
    class Program
    {
        static void Main(string[] args)
        {
            X.Print();
            Utility.Run();
        }
    }
    using B;
    class Utility
    {
        static public void Run()
        {
            X.Print();
        }
    }
}

Что должен выдать этот код? Текущим компилятором он не компилируется из-за using B; в середине, но очевидно, что он должен выдать то же самое, что и таких два отдельных файла:

namespace A.Z
{
    class Program
    {
        static void Main(string[] args)
        {
            X.Print();
            Utility.Run();
        }
    }
}
namespace A.Z
{
    using B;
    class Utility
    {
        static public void Run()
        {
            X.Print();
        }
    }
}

То есть, у нас находящиеся рядом выражения X.Print() интерпретируются по-разному. На using в середине файла можно и не обратить внимания, особенно если файлы и подлиннее, так что те, кто читают код, будут в недоумении, почему X.Print действует по-разному в разных местах файла, несмотря на то, что внутри никаких объявлений для X нет.

Таким образом, как мне кажется, правило придумано для того, чтобы код вёл себя по возможности единообразно, и не провоцировал ошибки.

Answer 2

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

Для однозначности.

В примере кода (во второй части) вы хотите объявить пространство имен Namespaces перед Main. По логике создателей C# (как и остальных языков семейств C/Java) оптимальнее считается выносить каждый класс в отдельный файл. Допускается даже делить один класс между несколькими файлами.

А если вам в середине какого-то класса надо поработать с другим Namespace вы можете использовать using

READ ALSO
Взаимодействие таблиц User, Student, Teacher

Взаимодействие таблиц User, Student, Teacher

Делаю подобие школьного сайтаВ приложении MVC 4 заимплементил кастомный membership provider, соответственно при помощи code first entity framework сгенерировал...

239
“Общение” 2 компьютеров средствами c#

“Общение” 2 компьютеров средствами c#

День добрый! Появилась у меня надобность "связать" 2 компа, чтобы один мог отсылать какую-то информацию, а другой - читать ее и обрабатыватьСначала...

218
Подсчет количества совпадение в списке

Подсчет количества совпадение в списке

Есть список словХочу получить результирующий словарь в котором я бы мог получить количество одинаковых строк

331
Алгебра 9 клас, help meee [требует правки]

Алгебра 9 клас, help meee [требует правки]

Ціну деякого товару спочатку знизили на 20% ,а потім підвищили на 30%Як і на скільки відсотків змінилася початкова ціна внаслідок цих двох переоцінок?

320