2010-09-12 33 views
9

有沒有辦法用Rtti來探索界面的屬性?Delphi Rtti:探索接口的屬性?

下面的代碼不起作用:

procedure ExploreProps; 
var 
    Ctx: TRttiContext; 
    RttiType: TRttiType; 
    RttiProp: TRttiProp; 
begin 
    RttiType := Ctx.GetType(TypeInfo(IMyInterface)); 
    for RttiProp in RttiType.GetProperties do 
    Writeln(RttiProp.ToString); 
end; 

有沒有人解決如何正確地做到這一點?

回答

4

接口是函數的集合。他們並不像對象那樣擁有屬性;這只是編譯器爲了讓它更容易編寫代碼而添加的一些語法糖。不同的是,在對象上,屬性允許受控訪問私有和受保護的成員,而在接口上,所有成員都是公共的,因此不需要屬性。

+0

好,但探索的接口方法不工作,要麼...只是通過使用RttiType.GetMethods取代了for循環,仍然沒有結果。 – 2010-09-12 15:21:23

+4

@Christian:我只是看了RTTI系統的代碼,標準庫中的很多接口都沒有爲它們生成RTTI。我不確定爲接口類型生成擴展RTTI的規則是什麼,因爲它似乎不同於爲類或記錄生成擴展RTTI。也許巴里凱利或艾倫鮑爾可以回答這個問題? – 2010-09-12 15:37:03

+0

爲了使TRttiType.GetMethods()報告接口的方法,接口類型需要應用'{M +}'。 – 2015-04-16 20:59:08

1

據我所知,不支持普通接口。您可以添加{$ M +},然後重試。

-1

遲到的答案,但您可以將您的參與者轉到TObject,例如

RttiType := Ctx.GetType(TObject(IMyInterface).ClassInfo); 
+0

這是不正確的和危險的。由於內存佈局接口不能轉換回對象。你將不得不向界面添加一個函數以返回對象(如在@ FLICKERs答案中)。 – 2017-05-07 12:04:35

2

在你的界面

function GetObject: TObject; 

添加此功能,並在類中實現它。 使用與RTTI GetObject函數例程

var 
    obj: IPerson; 
begin 
    obj := TPerson.Create; 
    Count := GetPropList(obj.GetObject.ClassInfo, tkAny, @List); 
end; 

請注意,你的類應該從TInterfacedPersistent繼承不TInterfacedObject

TPerson = class(TInterfacedPersistent, IPerson)