2010-09-03 3 views
6

Tôi gặp sự cố với các thuộc tính của loại IInterface. Tôi không biết cách chỉ định giá trị cho các thuộc tính này bằng RTTICác trường RTTI và Giao diện Delphi 2010

Dưới đây là ví dụ :.

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. 

Tôi phải viết tương tự intf1.B: = intf3; hoặc obj1.B = intf3;

bằng RTTI.

Điều này có khả thi không?

UPD Nó là công việc:

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 as ITestInterfacedClass)); nó là công việc, nhưng bên trong SetProperty tôi không muốn bất cứ điều gì quý tộc từ ITestInterfacedClass. – Mielofon

Trả lời

2

Thật không may, điều đó không làm việc vì mã chuyển đổi giao diện trong RTTI.pas không gọi QueryInterface. Nếu bạn đặt TValue bằng TValue.From<IInterface>, bạn không thể chuyển đổi TV sang một loại hình giao diện khác, ngay cả khi giao diện hỗ trợ loại đó. Vui lòng gửi cho QC.

Tạo TValue với TValue.From<ITestInterfacedClass> sẽ hoạt động. Nhưng sau đó bạn không thể sử dụng thói quen SetProperty đơn giản.

+0

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