Что такое пространство имен в net framework
Что такое пространство имен?
Чтобы гарантировать, что конфликты имен не возникнут ни в рамках .NET framework, ни в ваших собственных программах, используются пространства имен. Пространство имен просто предоставляет именованную группу классов, структур, перечислений, делегатов, интерфейсов и других пространств имен. В пространстве имен все объявленные элементы должны иметь уникальные имена. Однако одно и то же имя может дублироваться в разных пространствах имен. Это означает, что если вы решите создать математическую библиотеку, вы сможете назвать ее "Math", хотя Microsoft также предоставила математическую библиотеку.
Объявление пространства имен
Пространства имен объявляются с помощью ключевого слова namespace. Основной синтаксис для создания пространства имен очень прост, требуется только имя для новой группировки и блок кода, окруженный фигурными скобками:
Пример пространства имен
Чтобы продемонстрировать создание пространства имен, мы создадим некоторый код. Для начала создайте новое консольное приложение с именем NamespaceDemo. Если вы создаете проект с помощью Visual Studio, вы заметите, что автоматически созданный класс программы существует в пространстве имен, которое также называется "NamespaceDemo".
В одном файле кода можно определить несколько пространств имен. В этом случае мы добавим наше новое пространство имен в тот же файл, что и автоматически созданное. Добавьте следующее пространство имен и содержащий его класс в качестве основания кода, вне блока кода существующего пространства имен:
Этот код создает новое пространство имен с именем FirstNamespace и определяет класс "Test", содержащий один метод, который выводит строку в консоль. Теперь мы можем добавить второе пространство имен, опять же в конце кода:
Второе пространство имен также включает класс с именем "Test". Это не приводит к конфликту именования, поскольку два класса логически разделены пространствами имен. Это означает, что программа будет компилироваться без ошибок.
Аддитивные объявления пространств имен
Объявления пространства имен являются аддитивными. Это означает, что одно и то же определение пространства имен может быть включено в код в нескольких местах. Если сделано два или более соответствующих объявления, содержимое двух пространств имен объединяется в одно. Это особенно полезно, когда приложение может быть развернуто в разных версиях, поскольку дополнительный код может быть помещен в отдельные файлы кода. Затем файлы можно "поменять местами" для создания различных конфигураций сборки.
Добавление следующего кода расширит пространство имен FirstNamespace, добавив второй класс:
Ссылка на класс в другом пространстве имен
Пространства имен предотвращают конфликты между именами классов, изолируя содержимое каждого пространства имен. В приведенном выше примере код, созданный в классе "Program", не может получить доступ к классам в пространствах имен" FirstNamespace "и" SecondNamespace", просто ссылаясь на тестовый класс. Если основной метод программы будет обновлен следующим образом, код не будет компилироваться, так как не будет найден класс Test:
Директива using
Если бы Вы были обязаны префиксировать каждое использование каждого класса, структуры, перечисления и т. д. с именем пространства имен, содержащего его, ваш код станет громоздким. Чтобы избежать этого, можно использовать директиву using. Вы уже видели эту директиву в действии в начале почти каждого созданного вами файла кода.
Директива using сообщает компилятору, что пространство имен используется кодом. Когда компилятор находит имя класса, которое не распознается в текущем пространстве имен, он вместо этого проверяет каждое пространство имен, определенное в директиве using, чтобы увидеть, существует ли там элемент. Это означает, что полное имя элементов в таком ссылочном пространстве имен использоваться не требуется.
Чтобы добавить директиву using в код, ключевое слово using и имя пространства имен добавляются в начале файла кода. Например, чтобы добавить ссылку на пространство имен FirstNamespace, добавьте следующую строку в начале кода:
Теперь, когда компилятор знает, что это разрешено, чтобы проверить внутри "FirstNamespace", чтобы соответствовать имена классов, основной метод может быть обновлен, чтобы сделать его более удобным для чтения:
Создание псевдонимов
Директива using, как показано выше, может обеспечить гораздо более аккуратный код. Однако если включены две директивы using и каждое ссылочное пространство имен содержит соответствующее имя класса, создается конфликт имен. Чтобы показать эту проблему, добавьте вторую директиву using в код, ссылающийся на пространство имен SecondNamespace:
Теперь, когда оба дополнительных пространства имен ссылаются, компилятор не знает, какой тестовый класс использовать при создании объекта в основном методе. Попытка скомпилировать программу приводит к ошибке, которая объясняет, что "тTest" теперь является неоднозначной ссылкой.
Эта проблема может быть решена простым предоставлением полного имени при использовании тестовых классов. Однако имена пространств имен могут быть очень длинными, и это создает оригинальную проблему, затрудняющую чтение кода. Вместо этого директиву using можно использовать для создания псевдонима. Это позволяет связать более короткое имя с пространством имен и использовать его вместо пространства имен для квалификации класса.
Для создания псевдонима используется следующий синтаксис:
Alias-name - это имя псевдонима, которое будет отображаться в любом другом месте кода. namespace - это пространство имен для создания псевдонима. Чтобы применить псевдонимы для двух пространств имен, измените директивы using следующим образом:
Добавление псевдонимов удаляет возможность ссылаться на классы без предоставления псевдонима полного имени. Чтобы сделать возможным повторную компиляцию программы, измените объявление тестового объекта в методе Main для добавления псевдонима:
Вложенное пространство
Мы видели, как классы и другие элементы могут быть объявлены в пространстве имен, чтобы обеспечить группировку элементов кода и изоляцию имен для предотвращения конфликтов. Кроме того, пространства имен могут быть созданы в других пространствах имен для создания вложенной классификации. Это позволяет создавать глубокие древовидные структуры и осуществлять большой контроль над организацией модулей кода.
Рассмотрим следующие объявления вложенных пространств имен:
В этом случае существует три уровня пространства имен, каждый из которых объявлен внутри своего родителя. Класс "Test" объявляется в пределах третьего уровня вложенности. Чтобы получить доступ к этому классу, используя его полное имя, все три пространства имен должны быть указаны с каждым префиксом его дочернего элемента и разделены с помощью полной остановки. Таким образом, полное имя тестового класса - "Parent.Ребенок.Внук.Испытание".
Как и в случае однослойных пространств имен, директива using может быть добавлена для удаления требования использовать полное имя. В этом случае директива using будет иметь вид:
Более короткая нотация существует для объявления вложенного пространства имен, когда классы и другие объявления существуют только на самом глубоком уровне иерархии. Вместо того, чтобы определять каждое пространство имен по отдельности, пространства имен могут быть созданы в одном операторе, опять же с каждым пространством имен, разделенным полной остановкой. Следующий код функционально эквивалентен предыдущему образцу вложенных пространств имен:
Соглашение об именовании пространств имен
Предлагаемое пространство имен должно иметь следующий формат:
В этом соглашении об именовании CompanyName - это имя компании или бренда, которому принадлежит код. Для длинных названий компаний это должно быть уменьшено в размере, но стандартизировано по всей организации. TechnologyName относится к высокоуровневой технологии, к которой относятся классы в пространстве имен. Например, "Xml" для функций XML.
Feature - это необязательный элемент, который дает имя объекту в пространстве имен технологии. Наконец, пространство имен "Design" предлагается для пространств имен, содержащих функциональные возможности времени разработки. Примером пространства имен, содержащего элементы времени разработки пользовательских элементов управления мультимедиа для DVD-фильмов, может быть:
Пространства имен упорядочивают объекты, определенные в сборке. Сборки могут содержать несколько пространств имен, которые, в свою очередь, могут содержать другие пространства имен. Пространства имен предотвращают неоднозначность и упрощают ссылки при использовании больших групп объектов, таких как библиотеки классов.
Предотвращение конфликтов имен
На следующем рисунке показаны две иерархии пространства имен, содержащие объект с именем ListBox :
по умолчанию каждый исполняемый файл, созданный с помощью Visual Basic, содержит пространство имен с тем же именем, что и у проекта. Например, если вы определяете объект в проекте ListBoxProject , то исполняемый файл ListBoxProject.exe содержит пространство имен ListBoxProject .
Несколько сборок могут использовать одно и то же пространство имен. Visual Basic обрабатывает их как единый набор имен. Например, можно определить классы для пространства имен SomeNameSpace в сборке Assemb1 , а также определить дополнительные классы для того же пространства имен из сборки Assemb2 .
полные имена
Полные имена — это ссылки на объекты, имеющие префикс в виде имени пространства имен, в котором определен объект. Вы можете использовать объекты, определенные в других проектах, если создадите ссылку на класс (выбрав Добавить ссылку в меню Проект ) и затем используете полное имя объекта в коде. В следующем фрагменте кода показано, как использовать полное имя объекта из пространства имен другого проекта:
Полные имена предотвращают возникновение конфликтов имен, так как позволяют компилятору определить, какой именно объект используется. Однако сами эти имена могут получиться длинными и громоздкими. Чтобы обойти эту проблему, можно использовать оператор Imports для определения псевдонима— сокращенного имени, которое можно применить вместо полного имени. Например, в следующем примере кода создаются псевдонимы для двух полных имен, которые затем используются для определения двух объектов.
Если вы применяете оператор Imports без псевдонима, можно использовать все имена в данном пространстве имен без уточнения при условии, что они являются уникальными в данном проекте. Если проект содержит операторы Imports для пространств имен, где есть элементы с одинаковым именем, необходимо полностью уточнять это имя. Предположим, что проект содержал два следующих оператора Imports :
при попытке использовать Class1 без полного указания этого имени Visual Basic выдает ошибку, сообщающую, что имя Class1 неоднозначно.
Операторы уровня пространства имен
В пространстве имен можно определить такие элементы, как модули, интерфейсы, классы, делегаты, перечисления, структуры и другие пространства имен. Вы не можете определить такие элементы, как свойства, процедуры, переменные и события, на уровне пространства имен. Их следует объявить внутри контейнеров, таких как модули, структуры или классы.
Ключевое слово Global в полных именах
Можно использовать Global для доступа к другим пространствам имен корневого уровня, таким как Microsoft.VisualBasic, и любому пространству имен, сопоставленному с проектом.
Ключевое слово Global в операторах пространства имен
Можно также использовать ключевое слово Global в Namespace Statement. Это позволяет определить пространство имен из корневых пространств имен проекта.
Все пространства имен в проекте основаны на его корневом пространстве имен. Visual Studio назначает имя проекта в качестве корневого пространства имен по умолчанию для всего кода в проекте. Например, если проект называется ConsoleApplication1 , его программные элементы относятся к пространству имен ConsoleApplication1 . При объявлении Namespace Magnetosphere ссылки на Magnetosphere в проекте будут обращаться к ConsoleApplication1.Magnetosphere .
В следующих примерах используется ключевое слово Global для объявления пространства имен из корневого пространства имен для проекта.
В объявлении пространства имен Global не может быть вложенным в другое пространство имен.
Вы можете использовать Application Page, Project Designer (Visual Basic) для просмотра и изменения значения Корневое пространство имен проекта. Для новых проектов параметру Корневое пространство имен по умолчанию присваивается имя проекта. Чтобы сделать Global пространством имен верхнего уровня, можно очистить запись Корневое пространство имен , оставив поле пустым. Очистка значения Корневое пространство имен избавляет от необходимости использовать ключевое слово Global в объявлениях пространств имен.
В пространстве имен System.Globalization содержатся все классы культур и регионов, которые необходимо использовать для обеспечения поддержки различных форматов дат, чисел и даже различных календарей (классы GregorianCalendar, HebrewCalendar, JapaneseCalendar и т.д.). С помощью этих классов можно обеспечить отображение данных в различных представлениях в соответствии с локальными настройками пользователя.
Кодировка Unicode
Возьмем, к примеру, исландский символ Ogonek. Его можно получить за счет объединения базового символа 0x006F (представляющего маленькую латинскую букву "о") с комбинированными символом 0x0328 (представляющим сам символ Ogonek) и 0x0304 (представляющий комбинированный знак долготы над гласными — Macron). Комбинированные символы определяются в диапазоне от 0x0300 до 0x0345. Для рынков Америки и Европы существуют предопределенные символы, облегчающие работу со специальными символами. Символ Ogonek, например, может также получаться и за счет применения одного предопределенного символа OxO1ED.
Для азиатского рынка, где только один китайский язык требует свыше 80 000 символов, таких предопределенных символов не существует. В случае азиатских языков всегда используются комбинированные символы. В связи с этим возникает проблема с получением правильного количества отображаемых символов или текстовых элементов, а также базовых символов вместо комбинированных. В пространстве имен System.Globalization предлагается класс StringInfо, который позволяет решить эту проблему.
Ниже перечислены статические методы класса StringInfo, которые помогают работать с комбинированными символами:
GetNextTextElement
Возвращает первый текстовый элемент (базовый символ и все комбинированные) из указанной строки.
GetTextElementEnumerator
Возвращает объект TextElementEnumerator, который позволяет производить итерацию по всем текстовым элементам в строке.
ParseCombiningCharacters
Возвращает массив целых чисел, ссылающихся на все базовые символы в строке.
В одном отображаемом символе может содержаться множество символов Unicode. Во избежание проблем с этим, при написании приложений, предназначенных для международного рынка, не следует применять тип данных char, а использовать вместо него тип string, потому что в нем может размещаться текстовый элемент, содержащий как базовые, так и комбинированные символы, а в char — нет.
Культуры и регионы
Наиболее важным классом в пространстве имен System.Globalization, пожалуй, является класс CultureInfo. Этот класс позволяет представлять культуру и определять календари, формат дат и чисел, а также применяемый в данной культуре порядок сортировки строк.
Класс RegionInfo позволяет представлять региональные особенности (такие как валюта), а также указывать, применяется ли в регионе метрическая система. В некоторых регионах может использоваться сразу несколько языков. Одним из примеров является регион Испании, в котором есть баскская (eu-ES), каталонская (ca-ES), испанская (es-ES) и галисийская (gl-ES) культуры.
Подобно тому, как в одном регионе может использоваться множество языков, на одном языке могут говорить во множестве регионов, например, на испанском говорят в Мексике, Испании, Гватемале, Аргентине, Перу, и не только.
Специфические, нейтральные и инвариантные культуры
Специфические культуры ассоциируются с реальными существующими культурами, которые перечислены в упомянутом в предыдущем разделе документе RFC 1766. Они могут отображаться на нейтральные культуры. Например, de может служить нейтральной версией для таких специфических культур, как de-AT, de-DE, de-CH и т.д. de представляет собой сокращенное обозначение немецкого языка, a AT, DE и СН — сокращенное обозначение таких стран, как Австрия, Германия и Швейцария.
При переводе приложений выполнять перевод для каждого региона обычно не требуется, поскольку между вариантами немецкого языка, применяемого в Германии и Австрии, например, никакой особой разницы не существует. Поэтому вместо специфических культур для локализации приложений, как правило, достаточно использовать и просто нейтральные культуры.
Инвариантные культуры не зависят от реальных культур. При сохранении форматированных чисел и дат в файлах или отправке их по сети на сервер использование культуры, не зависящей ни от каких параметров пользователя, является наилучшим вариантом.
На рисунке показано, как выглядят отношения между этими типами культур:
CurrentCulture и CurrentUICulture
При настройке культур необходимо проводить различие между культурой, которая должна использоваться для пользовательской интерфейса, и той, что должна применяться для форматирования чисел и дат. Все культуры ассоциируются с потоком, и наличие этих двух типов культур, соответственно, означает, что к потоку могут применяться два параметра культуры. Класс Thread имеет свойства CurrentCulture и CurrentUICulture. Свойство CurrentCulture предназначено для указания культуры, которая должна использоваться для форматирования и сортировки, а свойство CurrentUICulture — той, что должна применяться для языка пользовательского интерфейса.
Пользователи могут изменять предлагаемое по умолчанию значение для CurrentCulture с помощью опций, предлагаемых в доступной через окно панели управления оснастке Regional and Language Options (Язык и региональные стандарты). С помощью этих опций также можно изменять предлагаемые по умолчания значения для формата чисел, времени и дат.
Значение CurrentUICulture от этих опций не зависит. Оно зависит от языка операционной системы. Хотя есть одно исключение: в случае установки Windows 7, Windows Vista или Windows ХР с многоязыковым пользовательским интерфейсом (MUI) язык пользовательского интерфейса может изменяться с помощью настроек региональных стандартов, и в таком случае они будут влиять на значение свойства CurrentUICulture.
Все эти настройки обеспечивают очень хорошее поведение по умолчанию, которое в большинстве случаев изменять не требуется. При необходимости, однако, параметры культуры можно легко модифицировать, изменяя значения обоих отвечающих за культуру свойств потока, скажем, таким образом, чтобы они представляли испанскую культуру, как показано в следующем фрагменте кода:
Теперь, когда понятно, как устанавливать культуру, можно рассмотреть вопросы, связанные с форматированием чисел и дат, на которое оказывает влияние параметр CurrentCulture.
Форматирование чисел
Числовые структуры Int16, Int32, Int64 и т.д. в пространстве имен System имеют перегруженные версии метода ToString(). Этот метод может применяться для создания различных представлений чисел в зависимости от локальных настроек. В случае структуры Int32 ToString() он имеет четыре таких перегруженных версии:
В версии без аргументов ToString() возвращает строку без всяких возможных вариантов форматирования. Однако этот метод может также принимать строку и класс, реализующий интерфейс IFormatProvider.
В строке указывается желаемый формат представления данных. Этот формат может представлять собой как стандартную, так и шаблонную строку форматирования чисел. В первом случае используются предопределенные обозначения: С — формат валюты; D — десятичный формат; Е — научный формат; F — формат с фиксированной точкой; G — общий формат; N — числовой формат; X — шестнадцатеричный формат.
Интерфейс IFormatProvider реализован классами NumberFormatInfо, DateTimeFormatInfо и CultureInfo. Этот интерфейс имеет единственный метод GetFormat(), который возвращает объект формата.
Класс NumberFormatInfo может применяться для определения специализированных форматов для чисел. В случае применения в нем конструктора по умолчанию создается независимый от культуры или инвариантный объект. С помощью свойства NumberFormatInfo можно изменять все опции форматирования, например знак положительных чисел, символ процента, разделитель групп чисел, символ валюты и многое другое. Статическое свойство InvariantInfо возвращает доступный только для чтения, независимый от культуры объект NumberFormatInfo, а статическое свойство CurrentInfo — объект NumberFormatInfo, в котором значения форматирования основаны на значениях свойства CultureInfo текущего потока.
Создадим простой консольный проект. В этом проекте первый пример демонстрирует отображение числа в формате культуры текущего потока. Во втором примере используется метод ToString() с аргументом IFormatProvider. Класс CultureInfo реализует интерфейс IFormatProvider, поэтому далее создается объект CultureInfo с использованием культуры French. И, наконец, в третьем примере демонстрируется изменение культуры текущего потока. Здесь культура изменяется на German с помощью свойства CurrentCulture экземпляра Thread:
Чтобы определить пространство имен используется следующая конструкция:
Вложенные пространства имен
Здесь мы определили вложенное пространство имен (namespace) MyNamespace . Теперь, чтобы использовать класс Data мы должны сделать так:
то есть, перед именем класса ( Data ) мы указываем название пространства имен ( MyNamespace ).
Более предпочтительным с точки зрения читабельности и поддержки проекта является организация пространства имен непосредственно через обозреватель решений Visual Studio . По умолчанию Visual Studio создает новое пространство имен в проекте на каждую папку в проекте. Например, создадим в нашем проекте попку с именем Base:
Создадим новый класс с названием BaseClass :
Обратите внимание на то, какое имя пространству имен присвоила Visual Studio :
По умолчанию, Visual Studio создала новый класс в пространстве имен составленному по шаблону: [Имя_проекта].[Папка_с_файлом]
Аналогичным образом мы можем создать поддиректорию в папке Base и пространство имен снова будет соответствовать физическому пути на диске, например:
Физически этот интерфейс располагается по пути /Base/Interfaces/IView.cs
Глобальные пространства имен и пространства имен уровня файла
Глобальные пространства имен
Глобальные пространства имен удобно использовать в том случае, если вам необходимо использовать это пространство имен во всем (или в большинстве файлов) проекте. Например, уже используемое нами пространство имен System можно определить как глобальное. Чтобы определить глобальное пространство имен необходимо перед его объявлением использовать ключевое слово global .
Теперь нам нет необходимости в каждом файле проекта для которого необходимо использование пространства имен System использовать конструкцию using System; .
Глобальные пространства имен можно определять в любом месте проекта, однако при этом, пространство имен с параметром global всегда должно находиться в коде выше, чем пространство имен без global :
Как можно видеть на скриншоте, Visual Studio указывает нам на то, что пространство имен с global необходимо перенести ВЫШЕ. И хоть мы имеем право определить глобальное пространство в любом удобном для нас месте, все же стоит придерживаться элементарных правил хорошего тона и постараться обеспечить поддержку нашего проекта в любом обозримом будущем. Поэтому все глобальные пространства имен лучше вынести в отдельный файл и назвать этот файл наиболее подходящим образом, например, GlobalUsings.cs или GlobalNamespaces.cs :
В обозревателе решений этот файл находится на самом верхнем уровне в проекте:
Пространства имен уровня файла
Итого
Читайте также: