2015-04-16 32 views
0

我有以下類,從中我想從成員獲得一些名字,如姓名使用TRttiContext屬性的名稱;

TInterface = interface(IXMLNode) 
    function Get_One: Boolean; 
    function Get_Two: Boolean; 
    function Get_Three: Boolean; 
    procedure Set_One(Value: Boolean); 
    procedure Set_Two(Value: Boolean); 
    procedure Set_Three(Value: Boolean); 
    property One: Boolean read Get_One write Set_One; 
    property Two: Boolean read Get_Two write Set_Two; 
    property Three: Boolean read Get_Three write Set_Three; 
end; 

TTesting = class(TXMLNode, TInterface) 
protected 
    function Get_One: Boolean; 
    function Get_Two: Boolean; 
    function Get_Three: Boolean; 
    procedure Set_One(Value: Boolean); 
    procedure Set_Two(Value: Boolean); 
    procedure Set_Three(Value: Boolean); 
end; 

讓我使用了一個TRttiContext

下面的方法名稱當運行它時,我總是有一個名爲RefCount的項目。

我不應該得到'One''Two''Three'的值嗎?

+0

順便說一句,用'I'前綴而不是'T'命名接口是正常的。 T是用於類和記錄。 –

+0

還有: http:// stackoverflow。com/questions/8679735/how-do-i-enumerate-all-properties-in-an-object-and-obtain-their-values –

回答

1

您的課程不包含除繼承TXMLNode之外的任何其他屬性。具體來說,它繼承了公共財產TInterfacedObject.RefCount

雖然它實現了一個包含屬性的接口,但類本身不包含屬性。這裏是類的定義:

type 
    TTesting = class(TXMLNode, TInterface) 
    protected 
    function Get_One: Boolean; 
    function Get_Two: Boolean; 
    function Get_Three: Boolean; 
    procedure Set_One(Value: Boolean); 
    procedure Set_Two(Value: Boolean); 
    procedure Set_Three(Value: Boolean); 
    end; 

正如你可以清楚地看到,沒有聲明那裏的屬性。

一些其他意見:

  • 默認情況下,RTTI不會產生對受保護成員。您需要指定使用$RTTI EXPLICIT表示您希望受保護成員的RTTI,如最近在此討論的那樣:Call a protected method (constructor) via RTTI。如果您要爲課程添加一個屬性,則可能需要使用$RTTI EXPLICIT PROPERTIES才能反映出來。
  • 您的循環for i := 0 to Length(PropList)在陣列末尾運行。循環至Length(...) - 1high(...)
+0

此外,RTTI不會爲接口中聲明的屬性生成,因爲編譯器實際上並不實際在接口中實現真正的屬性,就像它爲類一樣。接口屬性只是用於方便地調用接口方法的語言語法快捷方式。 –

0

這裏有很多問題。儘管在對方的回答細節,即使類有屬性正確定義,環路未正確構造:

for i:= 0 to Length(PropList) do S1:= PropList[i].name; PropList[i].ToString; 

這貫穿所有項目加一,但最終留下分配給S1只有一個項目(最後一個),這是你最初抱怨的。

現在,分配的PropList[i]碰巧已經超過了列表的末尾,應該生成一個編譯器警告,在循環結束後使用i,並生成一個可能的運行時異常。

你沒有在任何地方定義S1,也不清楚它在那裏做什麼。

我注意到,你在前面的帖子的評論中發佈了這個相同的錯誤循環代碼,並沒有解決。

我會展示正確的代碼,但我不確定你到底想要完成什麼,所以我會留給你自己想想。但它應該看起來更像這樣:

for i:= 0 to Length(PropList) do 
begin 
    S1:= PropList[i].name; // where is S1 being used? 
    PropList[i].ToString; // <-- this isn't doing anything 
end; 
+0

我想我已經在我的回答中介紹了這一點。真正發生的事情是調用者沒有使用該循環,而循環實際上只是爲該問題編寫的虛假代碼。 –

+0

是的,但考慮到該行的寫法,我認爲OP沒有意識到失蹤的開始/結束重要。當它顯示正確時,它看起來更明顯,它是錯誤的。 –