2012-02-29 57 views
11

考慮下面的例子(我使用德爾福XE)類:德爾福XE:類構造函數不會被調用,使用泛型

program Test; 

{$APPTYPE CONSOLE} 

type 
    TTestClass<T> = class 
    private 
    class constructor CreateClass(); 
    public 
    constructor Create(); 
    end; 

class constructor TTestClass<T>.CreateClass(); 
begin 
    // class constructor is not called. this line never gets executed! 
    Writeln('class created'); 
end; 

constructor TTestClass<T>.Create(); 
begin 
    // this line, of course, is printed 
    Writeln('instance created'); 
end; 

var 
    test: TTestClass<Integer>; 

begin 
    test := TTestClass<Integer>.Create(); 
    test.Free(); 
end. 

類constructur不會被調用,因此該行「類創建'不打印。 但是,如果我刪除概括並將TTestClass<T>轉換爲標準類TTestClass,則所有內容都按預期工作。

我是否錯過了仿製藥?或者它根本不起作用?

對此的任何想法都會被理解!

感謝, --Stefan--

+0

[documentation](http://docwiki.embarcadero.com/RADStudio/en/Methods#Class_Constructors)指出:「注意:泛型類或記錄的類構造函數可能執行多次,確切的次數在這種情況下執行的類構造函數取決於泛型類型的專用版本的數量,例如,專用TList 類的類構造函數可能會在同一個應用程序中執行多次。但它看起來有點像一個bug。 – 2012-02-29 15:14:04

+0

是的。我也讀過。除非「多次」包括零次,否則這確實看起來像一個錯誤。 – Schafsmann 2012-02-29 15:16:26

+0

一般規則:不要嘗試製作一個自包含的.dpr應用程序。總是至少有一個單位,並保持所有的DPR文件,你可以避開它。 – 2012-02-29 17:12:12

回答

9

看起來像一個編譯器錯誤。如果將TTestClass聲明和實現移動到單獨的單元,則相同的代碼有效。

unit TestClass; 

interface 
type 
    TTestClass<T> = class 
    private 
    class constructor CreateClass(); 
    public 
    constructor Create(); 
    end; 

var 
    test: TTestClass<Integer>; 

implementation 

class constructor TTestClass<T>.CreateClass(); 
begin 
    Writeln('class created'); 
end; 

constructor TTestClass<T>.Create(); 
begin 
    Writeln('instance created'); 
end; 

end. 
+1

+1我自己也得出了完全相同的結論! – 2012-02-29 15:19:17

+1

太好了,謝謝你解決這個問題!如果可以的話,我也會+1。其實我有我的班級在它自己的單位,但我只在.dpr文件中使用它。所以問題的答案是:泛型類的類構造函數不運行在.dpr文件中實例化的對象。 – Schafsmann 2012-02-29 15:41:28

+0

和我已經做了:) – Schafsmann 2012-02-29 15:46:51

11

我可以確認這是一個錯誤。如果該類的唯一實例化在.dpr文件中,那麼類構造函數不會運行。如果你創建另一個單元,即單獨的.pas文件,並從那裏實例化TTestClass<Integer>,那麼你的類構造函數將運行。我已經提交QC#103798

+1

在XE5中仍未修復。最糟糕的是你必須在單獨的.pas文件中聲明或實例化一個變量。而且你必須爲你的程序中使用的每個T做到這一點! – 2014-02-13 19:17:20

+2

在XE8中仍然沒有修復@LURD – 2015-04-10 12:06:40

+0

@LURD EBMT似乎強迫編碼人員按照WarrenP提到的將他們的手放在DPR文件上。 – Fr0sT 2015-10-14 07:00:48