Júnior Oliveira

C Sharp; Delphi; ASP .NET; PHP; Javascript;

RTTI e Class Helper no Delphi

07 Nov 2010 delphi, rtti

Olá pessoal, mais um post sobre RTTI (Run-Time Type Information) no Delphi porém agora eu explorei um pouco mais das novidades do Delphi XE como as novas classes para trabalhar com RTTI e o que pode ser feito usando Class Helper que já vem desde as versões anteriores.

Sobre RTTI não vou me fala muito pois já fiz um post sobre este assunto e Class Helper é um tipo que serve para extender uma classes adionando-a métodos e propriedades.

Para este exemplo vou usar o mesmo contexto do post anterior sobre RTTI para facilitar o entendimento e fazer uma comparação já que no post anterior trabalhei com a versão do Delphi 7 e neste post vou trabalhar com a versão do Delphi XE.

O primeiro código é de uma classe genêrica de modelo da estrutura da tabela no banco de dados. A primeira diferênça é que a mesma não precisa mais herdar da classe TPersistent que contém as directivas de compilação {$M+} ({$METHODINFO ON}) e {$M-} ({$METHODINFO OFF}) necessárias para implementar o acesso dos dados em memória e retirei também os métodos Create() e Destroy() pois não eram necessários.

1 type
2   TModel = class
3 
4   end;

O segundo código é de uma classe de modelo da estrutura da tabela Pessoa do banco de dados, note que ela herda a classe TModel e a segunda diferênça é que suas propridades não precisam mais estarem declaradas na sessão published da classe pode ser declaradas na sessão public e mesmo assim é possível acessa-lás em tempo de execução. Retirei também os métodos Create() e Destroy() pois também não eram necessários.

 1 uses
 2   Model;
 3 
 4 type
 5   TModelPessoa = class(TModel)
 6   private
 7     { Private declarations }
 8     FPessIden: Integer;
 9     FPessNome: String;
10 
11   public
12     { Public declarations }
13     property PessIden: Integer read FPessIden write FPessIden;
14     property PessNome: String read FPessNome write FPessNome;
15 
16   end;

O terceiro código é de uma classe que teria os métodos de operação na base de dados porém como no exemplo anterior retirei pois este não é o foco deste post e sim apenas mostrar uma utilização do RTTI e alterei a classe extendendo ela da classe TModel. Então vamos a explicação, o método fillProperty que é responsável por verificar as propriedades do objeto da classe principal TModel ou de uma classe que herde dela no caso TModelPessoa. Outro detalhe importante é a declaração da unit Rtti que contém os novos métodos responsáveis por acessar os dados em memória.

 1 uses
 2   TypInfo, Rtti, Classes, Dialogs, Model, Variants, SysUtils;
 3 
 4 type
 5   TController = class helper for TModel
 6   public
 7     { Public declarations }
 8     procedure fillProperties();
 9 
10   end;

Como descrito anteriomente o método responsável por acessar os dados em memória do objeto em tempo de execução. Note que em comparação com o post anterior é necessário apenas alguns objetos para realizar está operação, note também que utilizei for in para percorrer a lista de propriedades em memória que é outra novidade que não existia no Delphi 7, no exemplo anterior tinha utilizado for. Ao final será imprimida na tela as propriedades e os valores das propridades do objeto principal.

 1 procedure TController.fillProperties();
 2 var
 3   msg: TStringList;
 4   context: TRttiContext;
 5   prop: TRttiProperty;
 6 
 7 begin
 8   context := TRttiContext.Create();
 9   try
10     msg:= TStringList.Create();
11 
12     for prop in context.GetType(self.ClassType).GetProperties do
13       msg.Add(Format('%s: %s;', [prop.Name, VarToStr(prop.GetValue(self).AsVariant)]));
14 
15     ShowMessage(msg.Text);
16   finally
17     context.Free();
18   end;
19 end;

E por fim um trecho de código para você adicionar ao evento de um button por exemplo de como utilizar o método fillProperties da classe TController.

 1 var
 2   objPessoa: TModelPessoa;
 3 
 4 begin
 5   try
 6     objPessoa := TModelPessoa.Create();
 7     objPessoa.PessIden := 23;
 8     objPessoa.PessNome := 'Oliveira';
 9     objPessoa.fillProperties();
10   finally
11     FreeAndNil(objPessoa);
12   end;
13 end;

Este foi mais um post sobre RTTI no Delphi, espero que gostem. Em breve estárei postando um exemplo de como acessar propriedades que contém objetos e não apenas tipos primitivos usando RTTI.

Agradeço a visita e volte sempre.