2013-08-26 123 views
6

爲什麼在Delphi(XE)中產生以下錯誤?泛型類型的調用方法?

unit UTest; 

interface 


type 

TTest = class 
    public 
    procedure Foo<T>(A: T); 
end; 

implementation 

{ TTest } 

procedure TTest.Foo<T>(A: T); 
begin 
    A.Add('hej'); 
end; 

end. 

我認爲泛型德爾福簡單地插入通用功能,因此,如果與沒有一個Add(string)方法一類用它只會出錯誤。

回答

8

您的代碼會產生編譯錯誤,因爲編譯器無法知道T有一個名爲Add的方法接收單個字符串參數。

我認爲Delphi中的泛型類型只是插入到泛型函數中,所以只會在與沒有Add(string)方法的類型一起使用時出錯。

如果您使用Smalltalk或C++模板,那麼您的假設是準確的。但是,泛型與模板不同。對於泛型,您需要對類型參數應用一個約束。該約束需要告訴編譯器必須具有哪些屬性T

例如,可以將T約束爲從具有合適的Add方法的類派生。或者,您可以約束T以實現與合適的Add方法的接口。

文檔鏈接爲Delphi泛型約束:http://docwiki.embarcadero.com/RADStudio/en/Constraints_in_Generics

可應用於通用的約束是相當有限的,這是一種恥辱的東西。例如,我希望能夠限制某種類型具有某些數學運算符。例如,我希望能夠約束一個類型有+-運算符,說。然而,泛型和模板都有優點和缺點,所以我確實接受這些限制是由Delphi語言設計師作出合理的設計決定的結果。

+0

我想這樣做的原因是我有兩個類不共享基類(或接口),但一些方法簽名完全相同。我想這是有限的限制不可能的? – monoceres

+1

這是正確的。如果這些是模板,你會沒事的。但是,對於泛型而言,你只是運氣不佳。你遇到了同樣的問題,阻止我編寫可以在標量和複數值上運行的良好數學算法。 –

+1

這太糟糕了:(我想我將不得不恢復到RTTI和if語句(blersh) – monoceres