在泛型类型上调用方法?

时间:2013-08-26 14:25:12

标签: 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.

我认为Delphi中的泛型类型只是简单地插入到泛型函数中,因此只有在没有Add(string)方法的类型中使用时才会出错。

1 个答案:

答案 0 :(得分:8)

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

  

我认为Delphi中的泛型类型只是简单地插入到泛型函数中,因此只有在没有Add(string)方法的类型中使用时才会出错。

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

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

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

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