在泛型类型上调用方法?

mon*_*res 7 delphi generics delphi-xe

为什么以下在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.
Run Code Online (Sandbox Code Playgroud)

我认为Delphi中的泛型类型只是简单地插入到泛型函数中,因此如果与没有Add(string)方法的类型一起使用它只会出错.

Dav*_*nan 8

您的代码产生编译错误,因为编译器无法知道T有一个名为Add接收单个字符串参数的方法.

我认为Delphi中的泛型类型只是简单地插入到泛型函数中,因此如果与没有Add(string)方法的类型一起使用它只会出错.

如果您使用的是Smalltalk或C++模板,那么您的假设将是准确的.但是,泛型与模板不同.对于泛型,您需要对类型参数应用约束.约束需要告诉编译器T必须具有哪些属性.

例如,您可以约束T从具有合适Add方法的类派生.或者您可以约束T使用合适的Add方法实现接口.

Delphi通用约束的文档链接:http://docwiki.embarcadero.com/RADStudio/en/Constraints_in_Generics

可以应用的通用约束相当有限,这是一种耻辱.例如,我希望能够约束一个类型以拥有某些数学运算符.例如,我希望能够约束一个类型+-运营商,比方说.但是,泛型和模板都有利弊,因此我接受这些限制是德尔福语言设计师做出合理设计决策的结果.

  • 那是正确的.如果这些是模板,你会没事的.但是你只是运气不好.你遇到了同样的问题,阻止我编写可以在标量和复杂值上运行的优秀数学算法. (2认同)