Язык программирования C#9 и платформа .NET5
// Hexagon classpublic class Hexagon { /* Еще интересные методы... */ }}<b>// Square.cs</b>namespace MyShapes{// Square classpublic class Square { /* И еще интересные методы...*/}}На заметку! Рекомендуется иметь в каждом файле кода только один класс. В ряде приводимых ранее примеров такое правило не соблюдалось, но причиной было упрощение изучения. В последующих главах каждый класс по возможности будет располагаться в собственном файле кода.
Обратите внимание на то, что пространство
действует как концептуальный "контейнер" для определяемых в нем классов. Когда в другом пространстве имен (скажем,MyShapes) необходимо работать с типами из отдельного пространства имен, вы применяете ключевое словоCustomNamespaces, как поступали бы в случае использования пространств имен из библиотек базовых классов .NET Core:using// Обратиться к пространству имен из библиотек базовых классов.using System;// Использовать типы, определенные в пространстве имен MyShapes.using MyShapes;Hexagon h = new Hexagon();Circle c = new Circle();Square s = new Square();В примере предполагается, что файлы С#, где определено пространство имен
, являются частью того же самого проекта консольного приложения; другими словами, все эти файлы компилируются в единственную сборку. Если пространство именMyShapesопределено во внешней сборке, то для успешной компиляции потребуется также добавить ссылку на данную библиотеку. На протяжении настоящей главы вы изучите все детали построения приложений, взаимодействующих с внешними библиотеками.MyShapesРазрешение конфликтов имен с помощью полностью заданных имен
Говоря формально, вы не обязаны применять ключевое слово
языка C# при ссылках на типы, определенные во внешних пространствах имен. Вы можете использовать полностью заданные имена типов, которые, как упоминалось в главе 1, представляют собой имена типов, предваренные названиями пространств имен, где типы определены. Например:using// Обратите внимание, что пространство имен MyShapes большене импортируется!using System;MyShapes.Hexagon h = new MyShapes.Hexagon();MyShapes.Circle c = new MyShapes.Circle();MyShapes.Square s = new MyShapes.Square();Обычно необходимость в применении полностью заданных имен отсутствует. Они требуют большего объема клавиатурного ввода, но никак не влияют на размер кода и скорость выполнения. На самом деле в коде CIL типы всегда определяются с полностью заданными именами. С этой точки зрения ключевое слово
языка C# является просто средством экономии времени на наборе.usingТем не менее, полностью заданные имена могут быть полезными (а иногда и необходимыми) для избегания потенциальных конфликтов имен при использовании множества пространств имен, которые содержат идентично названные типы.
Предположим, что есть новое пространство имен
, где определены три класса, которые способны визуализировать фигуры в трехмерном формате:My3DShapes// Еще одно пространство имен для работы с фигурами.// Circle.csnamespace My3DShapes{// Класс для представления трехмерного круга.public class Circle { }}// Hexagon.csnamespace My3DShapes{// Класс для представления трехмерного шестиугольника.public class Hexagon { }}// Square.csnamespace 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();Разрешение конфликтов имен с помощью псевдонимов
Ключевое слово
языка C# также позволяет создавать псевдоним для полностью заданного имени типа. В этом случае определяется метка, которая на этапе компиляции заменяется полностью заданным именем типа. Определение псевдонимов предоставляет второй способ разрешения конфликтов имен. Вот пример:usingusing System;