Delphi Rtti para interfaces em um contexto genérico
ara uma estrutura, escrevi um invólucro que leva qualquer objeto, interface ou tipo de registro para explorar suas propriedades ou campos. A declaração de classe é a seguinte:
TWrapper<T> = class
private
FType : TRttiType;
FInstance : Pointer;
{...}
public
constructor Create (var Data : T);
end;
No construtor, tento obter as informações de tipo para etapas de processamento adicionai
constructor TWrapper<T>.Create (var Data : T);
begin
FType := RttiCtx.GetType (TypeInfo (T));
if FType.TypeKind = tkClass then
FInstance := TObject (Data)
else if FType.TypeKind = tkRecord then
FInstance := @Data
else if FType.TypeKind = tkInterface then
begin
FType := RttiCtx.GetType (TObject (Data).ClassInfo); //<---access violation
FInstance := TObject (Data);
end
else
raise Exception.Create ('Unsupported type');
end;
Gostaria de saber se esta violação de acesso é um bug no compilador delphi (estou usando o XE). Após uma investigação mais aprofundada, escrevi uma função de teste simples, que mostra que solicitar o nome da classe também produz essa exceção:
procedure TestForm.FormShow (Sender : TObject);
var
TestIntf : IInterface;
begin
TestIntf := TInterfacedObject.Create;
OutputDebugString(PChar (TObject (TestIntf).ClassName)); //Output: TInterfacedObject
Test <IInterface> (TestIntf);
end;
procedure TestForm.Test <T> (var Data : T);
begin
OutputDebugString(PChar (TObject (Data).ClassName)); //access violation
end;
Alguém pode me explicar, o que está errado? Eu também tentei o procedimento sem um parâmetro var que também não funcionou. Ao usar um procedimento não genérico, tudo funciona bem, mas para simplificar o uso do wrapper, a solução genérica seria boa, porque funciona para objetos e registros da mesma maneir
Atenciosamente
Cristã