通用方法类型推断

iam*_*osy 5 delphi generics type-inference

假设我有一个包含两个泛型方法的类:

TMyClass = class
  procedure DoWith<T: class> (obj: T);
  procedure DoFor<T: class> ( proc: TProc<T> );
end;
Run Code Online (Sandbox Code Playgroud)

现在,当我想用​​特定的类型参数调用这两个方法中的任何一个时,Delphi可以推断出该DoWith方法的类型,所以我可以用它们调用它

MyClass.DoWith <TButton> ( MyButton )
Run Code Online (Sandbox Code Playgroud)

要么

MyClass.DoWith ( MyButton )
Run Code Online (Sandbox Code Playgroud)

Delphi编译器很乐意编译它们.但是,如果我省略方法中的type参数DoFor,Delphi编译器会抱怨缺少的类型参数:

MyClass.DoFor<TButton>(procedure (Button: TButton) begin .... end);  // compiles


MyClass.DoFor(procedure (Button: TButton) begin .... end);  // doesn't compile
Run Code Online (Sandbox Code Playgroud)

现在我的问题是:这只是编译器的一个缺点,还是有任何逻辑上的原因(我还没想到)禁止编译器正确地推断出该DoFor方法的类型?

Ste*_*nke 5

它无法T从一个TProc<T>参数推断的原因是,那时TProc<TButton>是一个构造类型,没有任何原始信息TProc<T>.

要做到这一点,它必须从匿名方法签名中推断出不起作用的类型(我猜Barry Kelly可以更好地解释这一点,我认为他曾经写过关于lambdas的困难和Delphi中的类型推断).

Delphi编译器能够实现的唯一类型推断是类型为T的参数.即使有多个参数不经常工作,如果你有多个泛型类型参数也更少.

编辑:我发现了一个评论,其中Barry在Delphi编译器中解释了类型推断和lambdas的困难:http://www.deltics.co.nz/blog/posts/244/comment-page-1#comment- 107

  • @iamjoosy 我个人觉得这不合逻辑。如果编译器能更好地推断类型,我更喜欢它。我看不出有什么理由不能这样做。许多其他语言比 Delphi 更好地管理这一点。 (2认同)