Я знаю, что C # поддерживает вложения пространства имен, как и C ++, которые оба допускают код, который выглядит следующим образом …
namespace A {
namespace B {
...
}
}
Исходя из опыта C ++ и углубляясь в мир C #, я размышлял над тем, что выглядит как иерархическое вложение компонентов через все директивы using, которые должны быть выданы для использования .NET, например
using System.Collections;
using System.Collections.Generic;
Я уверен, что Microsoft планировала и спроектировала эти библиотеки для логической иерархической организации, но без помощи просмотра источника я не могу проверить, имеет ли System.Collections.Generic Generic как вложенное пространство имен коллекций, но я предполагаю, что это так, и что это было достигнуто с помощью вложений пространства имен, как это было видно с A и B. Теперь, когда я начинаю готовить вещи в своем исходном коде и объявлять код, который выглядит следующим образом
namespace C.D {
...
}
что именно я здесь достигаю в отношении иерархии? Представляю ли я в коде уникальный идентификатор пространства имен «C.D», где «.» это просто дружественный способ предложить иерархию, которая может существовать или не существовать в зависимости от структуры кода, или я неявно объявляю два пространства имен «C» и «D» с D, вложенным в C? Я сталкивался с этим вопросом, когда готовил пространство имен DevelopmentApplications к нашей кодовой базе C #, которая должна строго содержать все инструменты разработки, используемые для дополнения нашего программного обеспечения для помощи в его разработке. В этих инструментах я никогда не объявлял автономное вложение пространства имен DevelopmentApplications (это то, что я ДОЛЖЕН сделать в C ++) …
namespace DevelopmentApplications
{
...
}
…но вместо этого всегда создавайте приложения, которые идут как
namespace DevelopmentApplications.MyDevelopmentApp
{
...
}
Я знаю, что эта область является причиной путаницы для некоторых из-за следующего вопрос где автор изо всех сил пытается понять отношения между Foo.Bar.Baz и Foo.Bar. Там также обратное вопрос разработчика C #, входящего в C ++ land, который дает некоторое представление об этой проблеме.
Я предполагаю, что другой способ сформулировать вопрос состоит в том, что в C ++ использование оператора ‘::’ для полной квалификации типа, который я знаю, гарантирует, что код, в котором был объявлен тип, вложен глубоко в некоторую иерархию пространства имен. Но в C # используется «.» оператор, чтобы полностью определить некоторый тип, должен ли этот тип также существовать в некоторой глубоко вложенной иерархии пространства имен? Я предполагаю, что использование C # пространства имен, такого как A.B.C, не обязательно требует иерархических отношений между A B и C или что A B или C даже существуют как отдельные пространства имен.
Если кто-то может найти или знает соответствующую языковую спецификацию относительно этого синтаксиса, я бы с удовольствием его прочитал.
Раздел 9.2 спецификации C # 4.0 гласит:
Квалифицированный-идентификатор из Пространство имен декларирование может быть
одиночный идентификатор или последовательность идентификаторов, разделенных «.»
жетоны. Последняя форма позволяет программе определять вложенное пространство имен
без лексического вложения нескольких объявлений пространства имен. Например,namespace N1.N2 { class A {} class B {} }
семантически эквивалентно
namespace N1 { namespace N2 { class A {} class B {} } }
Вы заявляете:
Я предполагаю, что использование C # пространства имен, такого как A.B.C, не обязательно требует иерархических отношений между A B и C или что A B или C даже существуют как отдельные пространства имен.
Это предположение неверно. Пространство имен A.B.C
обязательно включает в себя пространство имен A
в глобальном пространстве имен, пространстве имен B
в пространстве имен A
и пространство имен C
в пространстве имен B
,
Немного факты о пространствах имен в C #:
Они коллективные. Вы можете объявить пространство имен в нескольких различных исходных файлах, и компилятор будет обрабатывать их все как одно и то же пространство имен.
Вы можете вкладывать пространства имен друг в друга, но гораздо чаще просто объявить вложенное пространство имен в другом исходном файле.
Eсть глобальное пространство имен, доступно каждому классу как global::