
RTTI является центральным элементом, на котором написано Delphi IDE, он существует со времен первого выпуска, однако я слышал от некоторых людей на протяжении многих лет, что они попытались использовать RTTI и нашли это слишком сложным и замысловатым, особенно по сравнению с Reflection API в Java и .NET. Вот это настоящий позор, поскольку возможность писать код для запроса подробной информации о других объектах, не зная заранее их типа, это действительно мощная возможность.
Однако, я думаю, что жалобы уйдут в прошлое с новым API. Оно было не только расширено, но стало гораздо более доступным и легким в использовании.
Одна из новых особенностей, которой я очень впечатлён — это поддержка атрибутов в среде Win32. Я работаю над большим примером, но здесь мы быстренько рассмотрим создание, а затем запрос пользовательских атрибутов.
Пользовательские атрибуты это просто классы, которые наследованы от TCustomAttribute. Они могут иметь свойства, методы и т.д., как и любой другой класс:
MyAttribute = class(TCustomAttribute)
private
FName: string;
FAge: Integer;
public
constructor Create(const Name : string; Age : Integer);
property Name : string read FName write FName;
property Age : Integer read FAge write FAge;
end;
Здесь никаких неожиданностей, конструктор описан именно так как ты этого ожидал.
Далее мы можем применить наш атрибут к классу:
TMyClass = class
public
[MyAttribute('Malcolm', 39)]
procedure MyProc(const s : string);
[MyAttribute('Julie', 37)]
procedure MyOtherProc;
end;
Здесь я применяю атрибут к обоим методам, но задаю разные параметры атрибуту. Порядок записи параметров соответствует их порядку в конструкторе. Применение атрибутов не ограниченно одними методами, вы можете применять атрибуты в свойствам, классам, к любым другим сущностям.
Конечно, нет смысла добавлять атрибуты, если вы не можете прочитать их откуда-нибудь, так что вот некоторые примеры кода, который использует новый API RTTI для запроса наших атрибутов, а также отображения деталей в ListBox:
procedure TForm3.Button1Click(Sender: TObject);
var
ctx : TRttiContext;
t : TRttiType;
m : TRttiMethod;
a : TCustomAttribute;
begin
ListBox1.Clear;
ctx := TRttiContext.Create;
try
t := ctx.GetType(TMyClass);
for m in t.GetMethods do
for a in m.GetAttributes do
if a is MyAttribute then
ListBox1.Items.Add(Format('Method = %s; Attribute = %s, Name = %s, Age = %d',
[m.Name, a.ClassName, MyAttribute(a).Name,
MyAttribute(a).Age]));
finally
ctx.Free;
end;
end;
Сначала я получил ссылку на RTTI контекст, и загрузил его с помощью ClassType моего класса. Затем я выполнил for..in по методам моего класса, и для каждого метода выполнил for..in по атрибутам. После этого я проверил, является ли атрибут моим пользовательским атрибутом, для них получил значения Name и Age, и отобразил их в списке ListBox.

Как я упоминал ранее, я работаю над другим примером, который более полезен, но, надеюсь, этот пример даст вам ощутить вкус некоторых новинок Delphi 2010.
Вы можете помочь в улучшении перевода.
translated.by/you/rtti-and-attributes-in-delphi-2010/into-ru
Переводчики: r3code