Изменения в компиляторе
RTTI
Основные изменения здесь связаны с расширением возможностей RTTI. Run Time Type Information – очень эффективное средство, позволяющее получать информацию о типах в Run Time режиме. В принципе о работе с RTTI можно писать романы, и, судя по различным опросам, изменения в данной области были наиболее ожидаемы.
Итак, прежде всего, появился модуль RTTI, в котором описывается много классов, существенно упрощающих использование RTTI в коде. Чуть подробнее об этом в описании изменений VCL.
Атрибуты
В данном контексте это специальные объекты, позволяющие сохранять дополнительную информацию об описываемых типах. Как указано в официальной документации, атрибуты расширяют обычную объектно-ориентированную модель аспектно-ориентированными элементами.
Проще всего показать работу атрибутов на примере. За основу я взял пример http://www.malcolmgroves.com/blog/?p=476/
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, RTTI; type 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('Julie', 37)] [MyAttribute('Malcolm', 39)] [MyAttribute('', 37)] procedure MyProc(const s : string); procedure MyOtherProc; end; TForm2 = class(TForm) Button1: TButton; ListBox1: TListBox; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation {$R *.dfm} constructor MyAttribute.Create(const Name : string; Age : Integer); begin FName:=Name; FAge:=Age; end; procedure TMyClass.MyProc(const s : string); begin end; procedure TMyClass.MyOtherProc; begin // end; procedure TForm2.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; procedure TForm2.Button2Click(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 begin if MyAttribute(a).Name='' then MyAttribute(a).Name:='Julie'; ListBox1.Items.Add(Format('Method = %s; Attribute = %s, Name = %s, Age = %d', [m.Name, a.ClassName, MyAttribute(a).Name, MyAttribute(a).Age])); end; finally ctx.Free; end; end; end.
Здесь, мы описываем класс, для которого задаем атрибуты, с предустановленными значениями (если угодно, с дополнительной информацией). Используя RTTI, мы получаем список этих атрибутов и их значений в Run Time и помещаем его в компонент TListBox. Как видно из второго примера, значения атрибутов доступны для редактирования.
Так же появилась директива компилятора RTTI, позволяющая задавать возможность получения RTTI информации для отдельных классов и записей
{$RTTI INHERIT|EXPLICIT [visibility clause]}
visibility-expression:
[vcPrivate],[vcProtected], [vcPublic], [vcPublished];
И еще одна директива – WEAKLINKRTTI – позволяет управлять процессом линковки RTTI информации для класса.
{$WEAKLINKRTTI ON} или {$WEAKLINKRTTI OFF}.
Продолжение следует…
Оставить комментарий