Variável tipo genérica em um formulário

Delphi

29/08/2013

Pessoal eu tenho essa função que cria instância de um objeto de um tipo genérico

function TForm1.CriaInstancia<T>: T;
var
    valor: TValue;
    ctx: TRttiContext;
    tipo: TRttiType;
    metodo: TRttiMethod;
    tipoInstancia: TRttiInstanceType;
begin
    tipo := ctx.GetType(TypeInfo(T));
    metodo := tipo.GetMethod('Create');
    //
    if Assigned(metodo) and tipo.IsInstance then
    begin
        tipoInstancia := tipo.AsInstance;
        //
        valor := metodo.Invoke(tipoInstancia.MetaclassType, []);
        // cria parametros
        //
        Result := valor.AsType<T>
    end;
end;



o que eu queria era que no meu form, tivesse uma variável do tipo genérica para que eu consiga passar no create do fomulário para a função cria instância
algo do tipo


  tteste = class
      teste: string;
  end;

 TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    function CriaInstancia<T>: T;
    { Private declarations }
  public
    variavelGenetica: ????????;

  end;

var
  Form1: TForm1;

implementation

uses RTTI;

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
      vavriavelGenerica := TTeste;

       CriaInstancia<variavelGenerica>
end;




Alguém saberia me dizer como fazer isso?

agradeço antecipadamente.
Rafael Reis

Rafael Reis

Curtidas 0

Respostas

Rafael Reis

Rafael Reis

29/08/2013

Ninguém pra ajudar?
GOSTEI 0
Gustavo Bretas

Gustavo Bretas

29/08/2013

E ae Rafael, tudo certo?

Cara, eu não sou muito bom com RTTI, mas eu fiz um método genérico pra criar formulários que talvez possa te ajudar!

Eu uso o método GetClass e FindClass para buscar a classe pelo nome, com string mesmo, só que pra conseguir usá-las, eu tenho que declarar as classes previamente, então declaro todas no arquivo de projeto pra ficar centralizado, o comando é:

RegisterClasses([Classe1, Classe2]);


Então prosseguindo, vc pode adicionar um parâmetro no construtor do formulário dessa forma:
constructor Create(AOwner: TComponent; NomeClasse : String); reintroduce;

constructor TForm2.Create(AOwner: TComponent; NomeClasse : String);
begin
  inherited Create(AOwner); // Essa linha chama o create original
  // Verifica se a classe foi declarada
  if GetClass(NomeClasse) <> nil then
  begin
    variavelGenetica := TComponentClass(FindClass(NomeClasse));
  end;
  // Só testar! rsrs
  CriaInstancia<variavelGenerica>
end;


No meu caso eu uso TComponentClass, pq ela é ancestral de TForm, e a função é somente para criar os formulários, mas acredito que vc possa usar a classe ancestral das suas variáveis, só substituir.

Daí pra frente vc tem na mão sua classe, e teoricamente pode chamar a função pra instanciar ela!

Espero ter ajudado, depois nos diga se deu certo!
GOSTEI 0
Marco Salles

Marco Salles

29/08/2013

Rafael Reis tudo bem ?

Bem o que vc quer não é dificil , mas vc esta esquecendo de um detalhe

Mesmo que vc defina esta variavel Genérica como acessar os métodos de uma classe especifica ??


vamos supor

variavelGenetica: TObject ; // esta classe é genérica , pois todas as outra derivam dela

ai vc instancia


variavelGenetica:=CriaInstancia<TTeste>;

para accessar os métodos vc tem que fazer um typcast

TTeste(variavelGenetica).MetodosDaClasseTeste

entendeu ???????
GOSTEI 0
POSTAR