【问题标题】:Invoke method on generic type?在泛型类型上调用方法?
【发布时间】:2013-08-29 01:56:45
【问题描述】:

为什么在 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) 方法的类型一起使用它只会出错。

【问题讨论】:

    标签: delphi generics delphi-xe


    【解决方案1】:

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

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

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

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

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

    可以应用的通用约束相当有限,这有点可惜。例如,我希望能够将类型限制为具有某些数学运算符。例如,我希望能够将类型限制为具有 +- 运算符,比如说。但是,泛型和模板各有利弊,因此我承认这些限制是 Delphi 语言设计者合理的设计决定的结果。

    【讨论】:

    • 我想要做上述的原因是我有两个类不共享一个基类(或接口),但一些方法签名完全相同。我想这在有限的约束下是不可能的?
    • 没错。如果这些是模板,你会没事的。但是你对泛型完全不走运。您遇到了同样的问题,这使我无法编写可以对标量和复数值进行运算的出色数学算法。
    • 太糟糕了 :( 我想我将不得不恢复到 RTTI 和 if 语句 (blersh)。
    • @monoceres 然后添加一个包含Add 方法的属性定义的接口,将其用作T 的接口约束,并在两个类中实现该接口。见bitbucket.org/jeroenp/besharp.net/commits/…
    • 这些类是从 WSDL (soap) 自动生成的。我不认为和他们打交道很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 2011-05-18
    • 2012-04-21
    • 2012-01-11
    • 2017-04-01
    • 1970-01-01
    • 2018-06-16
    相关资源
    最近更新 更多