Всем привет. Почему в данном примере:
// Пространства имен.
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# - это компилируемый язык а не интерпретируемый, а значит код не читается строчка за строчкой а строится синтаксическое дерево. И поэтому мне интересно не все ли равно где объявлять пространства имен?
Я думаю, компилятору было бы несложно динамически обновлять список привязок имён. Причиной правила является то, чтобы упростить понимание для нас, программистов, то есть, принцип наименьшего удивления.
Смотрите. Пускай у нас в другом файле есть такие декларации:
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
нет.
Таким образом, как мне кажется, правило придумано для того, чтобы код вёл себя по возможности единообразно, и не провоцировал ошибки.
Пространства имен сделаны не для компилятора, а для вас. Для того, чтобы не было пересечений одинаковых названий методов из разных пространств и вам не требовалось указывать весь длинный путь к нужному методу.
Для однозначности.
В примере кода (во второй части) вы хотите объявить пространство имен Namespaces перед Main. По логике создателей C# (как и остальных языков семейств C/Java) оптимальнее считается выносить каждый класс в отдельный файл. Допускается даже делить один класс между несколькими файлами.
А если вам в середине какого-то класса надо поработать с другим Namespace вы можете использовать using
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Делаю подобие школьного сайтаВ приложении MVC 4 заимплементил кастомный membership provider, соответственно при помощи code first entity framework сгенерировал...
День добрый! Появилась у меня надобность "связать" 2 компа, чтобы один мог отсылать какую-то информацию, а другой - читать ее и обрабатыватьСначала...
Есть список словХочу получить результирующий словарь в котором я бы мог получить количество одинаковых строк
Ціну деякого товару спочатку знизили на 20% ,а потім підвищили на 30%Як і на скільки відсотків змінилася початкова ціна внаслідок цих двох переоцінок?