Главная » Delphi » Delphi 2006 – Поддержка пространства имен

0

Одна из фундаментальных концепций технологии .NET, физически поддерживаемая средой выполнения CLR, — так называемое пространство имен: иерархическая система организации видимости идентификаторов (названий типов, переменных, функций). В системе Delphi эта концепция реализована с помощью модулей (units), когда программист размещает в интерфейсном разделе набор доступных для других модулей идентификаторов, обработка которых скрыта в разделе реализации. Нередко в прикладной программе по каким-либо причинам необходимо использовать уже существующий в библиотеках Delphi идентификатор в виде, например, собственной переменной. В соответствии с фундаментальной семантикой Паскаля, любой идентификатор оценивается компилятором прежде всего с точки зрения его локальности, и лишь потом, если не найдено его описание в пределах текущей подпрограммы (в виде локальной переменной или в виде параметра), поиск продолжается в пределах текущего класса, модуля и так далее. Поэтому, если в некотором операторе надо применить стандартный идентификатор какой- либо библиотеки Delphi, а он уже задействован в текущем модуле в качестве, например, локальной переменной, то перед этим стандартным идентификатором, отличающимся от локального описания, надо дополнительно через точку указать префикс: имя модуля, в интерфейсной части которого он описан. Следующий код ошибочен:

var IntToStr: String; begin

IntToStr := ‘5’;

IntToStr := IntToStr(10); end;

Идентификатор IntToStr используется и как локальная переменная, и как стандартная функция преобразования числа в строку, но так как идентификатор в первую очередь рассматривается на уровне локальных определений, то выражение IntToStr (10) считается ошибочным. Чтобы вызов работал корректно, укажем перед ним название стандартного модуля Sysutils:

var IntToStr: String; begin

IntToStr := ‘5’;

IntToStr := SysUtils.IntToStr(10); end;

С появлением большого числа новых классов .NET (несколько тысяч) ситуация с поддержкой соответствующих идентификаторов усложнилась тем, что подход Delphi ориентирован на одноуровневое представление (модуль-префикс и идентификатор), а классы .NET организованы в виде объемной иерархии, и к различным идентификаторам надо обращаться подчас через длинную цепочку названий стандартных классов-наследников.

Уровень такой иерархии в CLR называется пространством имен — в его текущих пределах и определяется некоторый ряд идентификаторов (например, типов данных). Эта концепция реализована и в языке Delphi для платформы .NET.

Проект Delphi задает так называемое пространство имен проекта по умолчанию. Все включенные в него модули вносят свой вклад в это пространство (предоставляют идентификаторы, описанные в их интерфейсных частях). Название этого пространства разработчик выбирает сам, указывая его следом за ключевым словом Program, например:

Program MyProjects.MyWork.Projl;

Все входящие в такой проект модули будут по умолчанию считаться относящимися к пространству имен MyProjects .MyWork. Projl, которое по отношению к ним должно использоваться как префикс. Так, модуль с заголовком:

unit Unitl;

в пределах данного проекта будет задавать пространство имен

MyProjects.MyWork.Proj1.Unitl.

Можно указать и явное пространство имен, формируемое неким модулем, если оно не должно быть привязано к текущему проекту:

Unit AnotherProjects.Lib.Additional.TestUnit;

Отличительная особенность пространства имен — запись его через точки, разделяющие отдельные идентификаторы. По правилам технологии .NET запись AnotherProjects.Lib.Additional определяла бы класс AnotherProjects, в котором имеется вложенное поле Lib (либо Lib как наследник класса Another Pro j ects), которое, в свою очередь, детализируется понятием Additional и так далее. В Delphi запись названия пространства имен характерна тем, что точки-разделители являются неотъемлемой частью одного целостного названия, а идентификаторы между точками сами по себе не несут никакого смысла в плане поддержки реализации иерархии классов. Такая реализация уже существует в .NET, а схема записи пространств имен Delphi с дополнительными точками между идентификаторами создана прежде всего для удобства и совместимости с принятой формой записи .NET.

Так, вышеописанный модуль будет храниться в файле AnotherProjects.Lib. Additional.TestUnit.pas — такой подход просто повышает наглядность проекта. Конечно, не исключено, что в каких-то ситуациях будут существовать и файлы AnotherProjects.Lib.Additional.pas, и AnotherProjects.Lib.pas, реализующие функциональность или ее отдельные особенности вышестоящих уровней иерархии в рамках Delphi, однако это совсем не обязательно.

При использовании пространства имен требуется, чтобы перед идентификатором стояло либо полное наименование этого пространства, либо оно не использовалось бы вообще. Так, описание переменной xyz будет искаться

компилятором как обычно — в пределах текущей процедуры или метода, 1 текущего модуля, и в интерфейсных разделах всех модулей, перечисленных « в разделе uses, а вот запись Another Projects .Lib. Additional .TestUnit. xyz подразумевает обращение к идентификатору xyz конкретного модуля (пространства имен) AnotherProjects. Lib. Additional .TestUnit. При этом будут неверны любые сокращенные формы записи:

TestUnit.XYZ

Lib.Additional.TestUnit.XYZ

^^ Отметим, что в сборку .NET (точнее, в метаинформацию о структуре сборки) ^^ включается информация об используемых в ней пространствах имен таким образом, что из названий пространств имен удаляется последний идентификатор с точкой перед ним. То есть, пространство имен модуля AnotherProjects.Lib.Additional. TestUnit будет представлено в метаданных соответствующей сборки проекта как AnotherProjects.Lib.Additional (без последнего названия модуля).

Одно и то же пространство имен может быть физически реализовано в виде нескольких файлов в формате .PAS. Для этого после названия пространства имен указывается ключевое слово in, за которым следует строка, а в ней через точку с запятой перечисляются модули, вся интерфейсная информация из которых включается в это пространство имен.

usee AnotherProjects.Lib.Additional in ‘work/TestUnit.pas;../add/GoUnit.pas';

Здесь пространство имен AnotherProjects.Lib.Additional задается интерфейсами модулей TestUnit и GoUnit. При этом если в них обнаружатся одинаковые идентификаторы, то компилятор сообщит о конфликте имен.

Бобровский С. И. Технологии Delphi 2006. Новые возможности. — СПб.: Питер, 2006. — 288 е.: ил.

По теме:

  • Комментарии