2010-09-03 9 views
6

Ich habe ein Problem mit den Eigenschaften des IInterface-Typs. Ich weiß nicht, wie Sie diesen Eigenschaften mit RTTI Werte zuweisenDelphi 2010 RTTI- und Interface-Felder

Hier ist ein Beispiel :.

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. 

Ich habe ein Analogon von intf1.B schreiben: = intf3; oder obj1.B = intf3;

mit RTTI.

Ist das möglich?

UPD Es ist Arbeit:

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 als ITestInterfacedClass)); es ist Arbeit, aber in SetProperty möchte ich nichts den Adel von ITestInterfacedClass. – Mielofon

Antwort

2

Leider funktioniert das nicht, weil der Schnittstelle Conversion-Code in RTTI.pas nicht Query-Interface nennen. Wenn Sie einen TValue mit TValue.From<IInterface> eingeben, können Sie ihn nicht in einen TValue eines anderen Schnittstellentyps konvertieren, selbst wenn die Schnittstelle diesen Typ unterstützt. Fühlen Sie sich frei, das QC zu übermitteln.

Das Erstellen des TValue mit TValue.From<ITestInterfacedClass> funktioniert jedoch. Aber dann können Sie die einfache SetProperty-Routine nicht verwenden.

+0

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

Verwandte Themen