Обычно необходимость в применении полностью заданных имен отсутствует. Они требуют большего объема клавиатурного ввода, но никак не влияют на размер кода и скорость выполнения. На самом деле в коде CIL типы всегда определяются с полностью заданными именами. С этой точки зрения ключевое слово
using
языка C# является просто средством экономии времени на наборе.
Тем не менее, полностью заданные имена могут
быть полезными (а иногда и необходимыми) для избегания потенциальных конфликтов имен при использовании множества пространств имен, которые содержат идентично названные типы.
Предположим, что есть новое пространство имен
My3DShapes
, где определены три класса, которые способны визуализировать фигуры в трехмерном формате:
// Еще одно пространство имен для работы с фигурами.
// Circle.cs
namespace My3DShapes
{
// Класс для представления трехмерного круга.
public class Circle { }
}
// Hexagon.cs
namespace My3DShapes
{
// Класс для представления трехмерного шестиугольника.
public class Hexagon { }
}
// Square.cs
namespace My3DShapes
{
// Класс для представления трехмерного квадрата.
public class Square { }
}
Если теперь вы модифицируете операторы верхнего уровня, как показано ниже, то получите несколько ошибок на этапе компиляции, потому что в обоих пространствах имен определены одинаково именованные классы:
// Масса неоднозначностей!
using System;
using MyShapes;
using My3DShapes;
// На какое пространство имен производится ссылка?
Hexagon h = new Hexagon; // Ошибка на этапе компиляции!
Circle c = new Circle; // Ошибка на этапе компиляции!
Square s = new Square; // Ошибка на этапе компиляции!
Устранить неоднозначности можно за счет применения полностью заданных имен:
// Теперь неоднозначности устранены.
My3DShapes.Hexagon h = new My3DShapes.Hexagon;
My3DShapes.Circle c = new My3DShapes.Circle;
MyShapes.Square s = new MyShapes.Square;
Разрешение конфликтов имен с помощью псевдонимов
Ключевое слово
using
языка C# также позволяет создавать псевдоним для полностью заданного имени типа. В этом случае определяется метка, которая на этапе компиляции заменяется полностью заданным именем типа. Определение псевдонимов предоставляет второй способ разрешения конфликтов имен. Вот пример:
using System;
using MyShapes;
using My3DShapes;
// Устранить неоднозначность, используя специальный псевдоним.
using The3DHexagon = My3DShapes.Hexagon;
//
На самом деле здесь создается экземпляр класса My3DShapes.Hexagon.
The3DHexagon h2 = new The3DHexagon;
...
Продемонстрированный альтернативный синтаксис
using
также дает возможность создавать псевдонимы для пространств имен с очень длинными названиями. Одним из пространств имен с самым длинным названием в библиотеках базовых классов является
System.Runtime.Serialization.Formatters.Binary
, которое содержит член по имени
BinaryFormatter
. При желании экземпляр класса
BinaryFormatter
можно создать следующим образом:
using bfHome = System.Runtime.Serialization.Formatters.Binary;
bfHome.BinaryFormatter b = new bfHome.BinaryFormatter;
...
либо с использованием традиционной директивы
using
:
using System.Runtime.Serialization.Formatters.Binary;
BinaryFormatter b = new BinaryFormatter;
...
На данном этапе не нужно беспокоиться о предназначении класса
BinaryFormatter
(он исследуется в главе 20). Сейчас просто запомните, что ключевое слово
using
в C# позволяет создавать псевдонимы для очень длинных полностью заданных имен или, как случается более часто, для разрешения конфликтов имен, которые могут возникать при импорте пространств имен, определяющих типы с идентичными названиями.
На заметку! Имейте в виду, что чрезмерное применение псевдонимов C# в результате может привести к получению запутанной кодовой базы. Если другие программисты в команде не знают о ваших специальных псевдонимах, то они могут полагать, что псевдонимы ссылаются на типы из библиотек базовых классов, и прийти в замешательство, не обнаружив их описания в документации.
Создание вложенных пространств имен
При организации типов допускается определять пространства имен внутри других пространств имен. В библиотеках базовых классов подобное встречается во многих местах и обеспечивает размещение типов на более глубоких уровнях. Например, пространство имен
IO
вложено внутрь пространства имен
System
, давая в итоге
System.IO
.
Шаблоны проектов .NET Core помещают начальный код в файле
Program.cs
внутрь пространства имен, название которого совпадает с именем проекта. Такое базовое пространство имен называется корневым. В этом примере корневым пространством имен, созданным шаблоном .NET Core, является
CustomNamespaces
:
namespace CustomNamespaces
{
class Program
{
...
}
}
На заметку! В случае замены комбинации
Program/Main
операторами верхнего уровня назначить им какое-либо пространство имен не удастся.
Вложить пространства имен
MyShapes
и
My3DShapes
внутрь корневого пространства имен можно двумя способами. Первый — просто вложить ключевое слово