2010-09-03 10 views
6

Tengo un problema con las propiedades del tipo de interfaz IInterface. No sé cómo asignar valores a estas propiedades usando RTTIDelphi 2010 RTTI y campos de interfaz

Aquí hay un ejemplo :.

program Project2; 

uses 
    Forms, RTTI, Windows, TypInfo; 
{$R *.res} 

type 
    ITestInterfacedClass = interface 
    ['{25A5B554-667E-4FE4-B932-A5B8D9052A17}'] 
    function GetA: ITestInterfacedClass; 
    procedure SetA(const Value: ITestInterfacedClass); 
    property A: ITestInterfacedClass read GetA write SetA; 
    function GetB: ITestInterfacedClass; 
    procedure SetB(const Value: ITestInterfacedClass); 
    property B: ITestInterfacedClass read GetB write SetB; 
    end; 


    TTestInterfacedClass = class(TInterfacedObject, ITestInterfacedClass) 
    private 
    FA: ITestInterfacedClass; 
    FB: ITestInterfacedClass; 

    function GetA: ITestInterfacedClass; 
    function GetB: ITestInterfacedClass; 
    procedure SetA(const Value: ITestInterfacedClass); 
    procedure SetB(const Value: ITestInterfacedClass); 

    public 
    property A: ITestInterfacedClass read GetA write SetA; 
    property B: ITestInterfacedClass read GetB write SetB; 
    end; 


    { ITestInterfacedClass } 
.... 

procedure SetProperty(aLeft: TObject {IInterface}; aNameProp: string; aRight: IInterface); 
var 
    RttiContext: TRttiContext; 
    RttiType: TRttiType; 
    RTTIProperty: TRttiProperty; 
begin 
    RttiContext := TRttiContext.Create; 

    RTTIType := RttiContext.GetType(TTestInterfacedClass); 
    RTTIProperty := RTTIType.GetProperty(aNameProp); 
    if RTTIProperty.PropertyType.TypeKind = tkInterface then 
    RTTIProperty.SetValue(aLeft, TValue.From<IInterface>(aRight)); 
end; 

var 
    obj1: TTestInterfacedClass; 
    intf1, intf2, intf3: ITestInterfacedClass; 

begin 
    obj1 := TTestInterfacedClass.Create; 
    intf1 := obj1; 
    intf2 := TTestInterfacedClass.Create; 
    intf3 := TTestInterfacedClass.Create; 

    intf1.A := intf2; 

    // intf1.B := intf3; 
    SetProperty(obj1, 'B', intf3); 

end. 

tengo que escribir un análogo de intf1.B: = intf3; o obj1.B = intf3;

usando RTTI.

¿Esto es posible?

UPD Es un trabajo:

procedure SetProperty(aLeft: TObject; aNameProp: string; aRight: IInterface); 
var 
    RttiContext: TRttiContext; 
    RttiTypeInterface: TRttiInterfaceType; 
    RTTIProperty: TRttiProperty; 
    Value: TValue; 
begin 
    RttiContext := TRttiContext.Create; 

    RTTIType := RttiContext.GetType(aLeft.ClassType); 
    RTTIProperty := RTTIType.GetProperty(aNameProp); 
    if RTTIProperty.PropertyType.TypeKind = tkInterface then 
    begin 
    TValue.Make(@aRight, RTTIProperty.PropertyType.Handle, Value); 
    RTTIProperty.SetValue(aLeft, Value); 
    end; 
end; 
+0

RTTIProperty.SetValue (aLeft, TValue.From (aRight como ITestInterfacedClass)); es un trabajo, pero dentro de SetProperty no deseo nada de la nobleza de ITestInterfacedClass. – Mielofon

Respuesta

2

Por desgracia, eso no funciona debido a que el código de conversión de interfaz en RTTI.pas no llama a QueryInterface. Si coloca un TValue con TValue.From<IInterface>, no puede convertirlo a un TValue de un tipo de interfaz diferente, incluso si la interfaz admite ese tipo. Siéntase libre de enviar eso a QC.

La creación de TValue con TValue.From<ITestInterfacedClass> funciona bien. Pero luego no puedes usar la rutina simple SetProperty.

+0

TValue.Make (@aRight, RTTIProperty.PropertyType.Handle, Value); RTTIProperty.SetValue (aLeft, Value); – Mielofon

Cuestiones relacionadas