2010-03-23 45 views
8

我有兩個問題(其中至少有一個是D2010和動態的實例化有關RTTI)2010年德爾福:無論發生在TRTTIConstructor?

  1. 我在讀這似乎是一個conference talk巴里·凱利的箔,並在P發現。 13看起來很有趣的東西:TRTTIConstructor.Invoke。在相鄰的項目符號中,可以找到「動態構建實例而不需要虛擬構造函數和元類」。這似乎是一個偉大的功能(和我所需要的,順便說一句)!但是,當我查看D2010文檔(ms-help://embarcadero.rs2010/vcl/Rtti.html)時,我無法找到它。它被撤銷了嗎?
  2. 如果類名存儲在字符串中,創建類的實例的最簡單方法是什麼?

回答

10

我認爲功能已被吸收到TRttiMethod中。它具有IsConstructor,IsDestructor和IsClassMethod屬性,因此它可以用於「特殊」類型的方法以及普通方法。

對於問題2,嘗試這樣的事情:

function GetConstructor(val: TRttiInstanceType): TRttiMethod; 
var 
    method: TRttiMethod; 
begin 
    for method in val.GetMethods('Create') do 
    begin 
     if (method.IsConstructor) and (length(method.GetParameters) = 0) then 
     exit(method); 
    end; 
    raise EInsufficientRTTI.CreateFmt('No simple constructor available for class %s ', 
            [val.MetaclassType.ClassName]); 
end; 

這個發現稱爲Create最高的構造函數沒有參數。如果你知道你在找什麼,你可以修改它來尋找其他簽名的構造函數。然後在結果上撥打Invoke

+1

再次感謝梅森的例子!你(和SO中的其他人)幾乎接近文檔差距。非常感謝。 + 1 – conciliator 2010-03-23 14:50:32

+1

很高興幫助。我在那個演講中,D2010當時還處於測試階段。看起來好像有些事情從那時起變成了最終版本。我想知道爲什麼HasAttribute被刪除。這將是非常有用的! – 2010-03-23 14:59:56

2

雖然您可以調用.GetMethod()來獲取構造函數,但您也可以執行以下操作來爲構造函數構造不帶參數的對象的實例。

function CreateInstance(aType : TRttiType) : TObject; 
begin 
    // Option #1 
    result := aType.AsInstance.MetaclassType.Create; 
    // Option #2 
    result := aType.GetMethod('Create').Invoke(aType.AsInstance.MetaclassType,[]); 
end; 

如果知道基類型,您可以按照您的意願鍵入類的類型以傳遞參數。 下面是一個創建組件

result := TComponentClass(aType.AsInstance.MetaClassType).Create(OwnerValue);

+0

謝謝羅伯特!對於我目前的項目,我事先知道基礎類型,因此您答案中的最後一行就是醫生的命令。 (+1)但是,當我運行Button時出現訪問衝突:= TButton(RType.ClassType).Create(self);其中Button:TButton和self是所有者窗體,並且RType:由RType創建的TRTTIType:= RContext.FindType('StdCtrls.TButton'); (並且上下文已經創建)。我究竟做錯了什麼? – conciliator 2010-03-24 08:10:34

+0

試試這個: Button:= TComponentClass(RType.AsInstance.MetaclassType).Create(Self)as TButton; – 2010-03-24 08:48:59

+0

謝謝,VilleK。唉,我仍然有訪問違規。我猜我應該就此做一個單獨的帖子。 – conciliator 2010-03-24 09:38:57