2009-09-08 82 views
3

嘿,所有,首先抱歉我的英語不好。 考慮以下(不實際的代碼):基於RTTI信息的德爾福呼叫方法

IMyInterface = Interface(IInterfce) 
    procedure Go(); 
end; 

MyClass = class(IMyInterface) 
    procedure Go(); 
end; 

MyOtherClass = class 
published 
    property name: string; 
    property data: MyClass; 
end; 

我設置使用RTTI 「MyOtherClass」 屬性。對於字符串屬性很容易,但我的問題是:

如何獲得對「數據」(MyClass)屬性的引用,以便我可以調用Go()方法?

我想要做這樣的事情(僞代碼):

for i:= 0 to class.Properties.Count 
    if (propertyType is IMyInterface) then 
    IMyInterface(class.properties[i]).Go() 

(如果只有這是C#:()

PS:這是在Delphi 7(我知道,即使更糟)

+1

德爾福2010年RTTI得到了很大的改進。有一個易於使用的單位稱爲rtti.pas。 換句話說切換到d2010,你會得到更少的痛苦。 – 2009-09-09 10:28:52

+0

我很想這麼做,delphi中有許多很酷的新功能......但在這個項目中,我真的不能:/ - 但我會試着去得到2010年的試用版,只是爲了看看它是如何工作的,說服我的老闆:D – Leo 2009-09-09 12:58:22

+0

目前embarcadero正在德國巡迴演出。 http://devtracks.de – 2009-09-09 13:29:17

回答

4

如果字符串屬性很簡單,就像您說的那樣,那麼我假設您從TypInfo單位調用GetStrPropSetStrProp。對於GetObjectPropSetObjectProp,類型屬性可以同樣容易。

if Supports(GetObjectProp(Obj, 'data'), IMyInterface, Intf) then 
    Intf.Go; 

如果你並不真正需要的接口,你知道data酒店類型TMyClass,那麼你就可以多一點直接去:

(GetObjectProp(Obj, 'data') as TMyClass).Go; 

這就需要物業有一個非空值。

如果你不知道你想要的財產的名稱,那麼你可以使用TypInfo中的其他東西來搜索它。例如,這裏是一個函數,它將查找具有實現IMyInterface值的對象的所有已發佈屬性;它會按順序調用Go

procedure GoAllProperties(Other: TObject); 
var 
    Properties: PPropList; 
    nProperties: Integer; 
    Info: PPropInfo; 
    Obj: TObject; 
    Intf: IMyInterface; 
    Unk: IUnknown; 
begin 
    // Get a list of all the object's published properties 
    nProperties := GetPropList(Other.ClassInfo, Properties); 
    if nProperties > 0 then try 
    // Optional: sort the list 
    SortPropList(Properties, nProperties); 

    for i := 0 to Pred(nProperties) do begin 
     Info := Properties^[i]; 
     // Skip write-only properties 
     if not Assigned(Info.GetProc) then 
     continue; 

     // Check what type the property holds 
     case Info.PropType^^.Kind of 
     tkClass: begin 
      // Get the object reference from the property 
      Obj := GetObjectProp(Other, Info); 
      // Check whether it implements IMyInterface 
      if Supports(Obj, IMyInterface, Intf) then 
      Intf.Go; 
     end; 

     tkInterface: begin 
      // Get the interface reference from the property 
      Unk := GetInterfaceProp(Obj, Info); 
      // Check whether it implements IMyInterface 
      if Supports(Unk, IMyInterface, Intf) then 
      Intf.Go; 
     end; 
     end; 
    end; 
    finally 
    FreeMem(Properties); 
    end; 
end; 
+0

謝謝Rob,你的解決方案完美地解決了我的問題。這正是我所期待的 - 你應該得到RTTI-Hero徽章:) – Leo 2009-09-09 12:55:06

2

你可以得到的陣列中的所有出版致電GetPropInfos(MyClass.ClassInfo有產者),這是PPropInfo指針數組。而且你可以通過調用GetTypeData它在從PPropInfo特定類型的數據獲取,它返回一個PTypeData。它指向的記錄將包含你的信息e尋找關於類的參考。