Изменения в компиляторе
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}.
Продолжение следует...
Ссылки по теме