(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Delphi 2010 RTTI - Основы

Источник: delphi2010
Александр Божко

В Delphi 2009 как и в предыдущих версиях, RTTI был ограничен элементами, размещенными в Published секции.

У вас был доступ к указателям на свойства, поля и методы объекта. Если потратить немного времени на обучение, то старая версия RTTI превращалась в довольно мощный механизм. Однако, мощь RTTI предыдущих версий смотрится весьма скромно по сравнению с тем, что стало возможным в Delphi 2010.

В Delphi 2010 вы можете извлекать RTTI информацию практически отовсюду. Выбор, какая информация должна быть доступна, остается за вами, этим управляет новая директива $RTTI. Поведение по умолчанию определено в System.pas, фрагмент которого приведен ниже, свойства и методы теперь доступны посредствам RTTI как в Published, так и в Public секциях, а поля доступны во всех секциях.

Section of System.pas:
{ RTTI Visibility }
type
  TVisibilityClasses = set of (vcPrivate, vcProtected, vcPublic, vcPublished);

const
  { Эти константы отображают текущие установки, встроенные в компилятор.
    Обычно для классов они наследуются от TObject.
    }
  DefaultMethodRttiVisibility = [vcPublic, vcPublished];
  DefaultFieldRttiVisibility = [vcPrivate..vcPublished];
  DefaultPropertyRttiVisibility = [vcPublic, vcPublished];

type
  { Настройки RTTI по-умолчанию}
  {$RTTI INHERIT
      METHODS(DefaultMethodRttiVisibility)
      FIELDS(DefaultFieldRttiVisibility)
      PROPERTIES(DefaultPropertyRttiVisibility)}

Сама по себе RTTI информация не будет представлять ценности до тех пор, пока у вас не будет удобного доступа к ней.  Новый модуль RTTI.pas предоставляет простой и элегантный метод доступа к этим данным. Гибкость классов, без головной боли с управлением памятью (Memory Management) стала ключевым моментом для нового проекта. Поскольку RTTI доступ реализован через контекст, вместе с высвобождением контекста высвобождаются все RTTI объекты, созданные в рамках контекста.

var
 c : TRttiContext;
begin
  c := TRttiContext.Create;
  try
     // RTTI Access code here
  finally
   c.free;
  end;
end;

Если вы откроете RTTI.pas, вам следует обратить внимание на то, что TRttiContext  не является объектом, это - запись (Record), но не смущайтесь по поводу того, что вы должны вызывать .Create и .Free так же как и для объекта. Это обусловлено необходимостью высвобождать пул RTTI объектов, которые могут быть созданы. Хотя help файл рекомендует не высвобождать их, лично я предпочитаю делать это.

Ввиду большого числа возникших вопросов, я дам более детальное разъяснение.

TRttiContext предоставляет несколько ключевых методов, которые позволяют вам получать доступ к типам в системе.

function GetType(ATypeInfo: Pointer): TRttiType; overload;
function GetType(AClass: TClass): TRttiType; overload;
function GetTypes: TArray<TRttiType>;
function FindType(const AQualifiedName: string): TRttiType;

Например, следующий код  вернет TRttiType класс, репрезентующий, TButton.

var
  c : TRttiContext;
  t : TRttiType;
begin
  c := TRttiContext.Create;
  try
    // Via a String
    t := c.FindType('StdCtrls.TButton');

    // Via the pTypeInfo Pointer
    t := c.GetType(TButton.ClassInfo);

    // Via the class type
    t := c.GetType(TButton);
  finally
    c.Free;
   end;
end;

TRttiType содержит много функций, которые позволяют вам запрашивать члены класса на предмет их типа.

var
  c : TRttiContext;
  t : TRttiType;
begin
  c := TRttiContext.Create;
  try
    // Via a String
    t := c.FindType('StdCtrls.TButton');

    // Via the pTypeInfo Pointer
    t := c.GetType(TButton.ClassInfo);

    // Via the class type
    t := c.GetType(TButton);
  finally
    c.Free;
   end;
end;

Так, например, следующее консольное приложение будет показывать все методы TButton.

program Project10;
{$APPTYPE CONSOLE}
uses
  StdCtrls, TypInfo, Rtti;

var
 c : TRttiContext;
 m : TRttiMethod;
begin
   c := TRttiContext.Create;
   for m in c.GetType(TButton).GetMethods do
   begin
     Writeln(m.ToString);
   end;
   c.Free;
   readln;
end.

Результат.

constructor Create(AOwner: TComponent)
class destructor Destroy
procedure Click
... (Many Lines Removed) ...
procedure AfterConstruction
procedure BeforeDestruction
procedure Dispatch(var Message)
procedure DefaultHandler(var Message)
class function NewInstance: TObject
procedure FreeInstance
class destructor Destroy

Перейдем на следующий уровень.  Приведенный ниже код создает TStringList используя RTTI, вызывая метод Add и получая доступ к свойству Text. Здесь приведен не совсем практичный пример, он создан только для того, что бы показать отдельные возможности. Вы должны обратить внимание на то, что для сохранения значений используется тип TValue. TValue может как сохранять, так и извлекать тип.

 
program Project11;
{$APPTYPE CONSOLE}
uses
  StdCtrls, TypInfo, Classes, Rtti;

var
 c : TRttiContext;
 m : TRttiMethod;
 t : TRttiInstanceType;
 SL : TValue;
 Lines : TValue;
begin
   c := TRttiContext.Create;
   t := (c.FindType('Classes.TStringList') as TRttiInstanceType);
   SL := t.GetMethod('Create').Invoke(t.MetaclassType,[]);
   t.GetMethod('Add').Invoke(SL,['Hello Do you like my hat?']);
   t.GetMethod('Add').Invoke(SL,['I like that hat, what a party hat!']);
   Lines := t.GetProperty('Text').GetValue(SL.AsObject);
   Writeln(Lines.ToString);
   c.Free;
   readln;
end.

Результат.

Hello Do you like my hat?
I like that hat, what a party hat!

Хотя может показаться, что TValue работает подобно variant, TValue не является заменой Variant. Характерно, что если вы назначаете TValue  определенный тип, вы должны извлекать его как этот назначенный тип. Например, вы не сможете назначить TМalue  integer, а извлечь string, в результате вы получите Invalid Type Cast.

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

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 12.10.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Enterprise Connectors (1 Year term)
Delphi Professional Named User
TeeChart for .NET Standard Business Edition 2017 single license
Oracle Database Standard Edition 2 Named User Plus License
EMS SQL Management Studio for InterBase/Firebird (Business) + 1 Year Maintenance
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Один день системного администратора
3D и виртуальная реальность. Все о Macromedia Flash MX.
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100