Delphi 泛型方法类型推断

Delphi 泛型方法类型推断,delphi,generics,type-inference,Delphi,Generics,Type Inference,假设我有一个具有两个泛型方法的类: TMyClass = class procedure DoWith<T: class> (obj: T); procedure DoFor<T: class> ( proc: TProc<T> ); end; 或 Delphi编译器将很高兴地编译这两个。 但是如果我在DoFor方法中省略了type参数,Delphi编译器会抱怨缺少type参数: MyClass.DoFor<TButton>(proced

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

TMyClass = class
  procedure DoWith<T: class> (obj: T);
  procedure DoFor<T: class> ( proc: TProc<T> );
end;

Delphi编译器将很高兴地编译这两个。 但是如果我在
DoFor
方法中省略了type参数,Delphi编译器会抱怨缺少type参数:

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


MyClass.DoFor(procedure (Button: TButton) begin .... end);  // doesn't compile
MyClass.DoFor(过程(按钮:TButton)开始…结束);//汇编
DoFor(过程(按钮:TButton)开始…结束);//不编译

现在我的问题是:这只是编译器的一个缺点,还是有任何逻辑原因(我还没有弄清楚)这使得编译器无法正确推断
DoFor
方法的类型?

它无法从
TProc
参数推断
T
的原因是当时
TProc
是一个构造类型,没有任何信息表明它最初是
TProc

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

Delphi编译器能够进行的唯一类型推断是T类型的参数。即使有多个不经常工作的参数,如果有多个泛型类型参数,甚至更少


编辑:我发现Barry在评论中解释了Delphi编译器中类型推断和lambdas的困难:

这看起来像是编译器的一个限制。泛型类型推断在Delphi中非常弱。谢谢Stefan:您的回答让我了解了缺少的部分,以理解这种编译器行为是有逻辑原因的。@iamjoosy我个人认为这是不合逻辑的。我更希望编译器能更好地推断类型。我看不出它没有理由不这样做。“很多其他语言都比Delphi更好地处理这个问题。”DavidHeffernan起初我自己在编译器bahaviour中看不到任何逻辑,因此我的问题就在这里。但是Stefan的回答让我大开眼界,因为他解释了编译器是如何处理表达式的:它从内部到外部构造实际类型,因此首先用TButton类型构造匿名函数,然后在周围的过程中使用该类型进行操作,此时编译器已经“忘记”了匿名函数是由修饰周围函数的同一类型参数T构造而成的。@DavidHeffernan这并不是说无法更好地处理它,但它解释了编译器在当前实现中存在问题的原因。@iamjoosy在我看来,根据我的用法,编译器在泛型推理方面相当糟糕。很明显,这取决于它的实现方式。我个人认为,如果说编译器的实现方式意味着它相当蹩脚,那就没有什么深刻的见解。从这个问题上看,这是非常清楚的。
MyClass.DoWith ( MyButton )
MyClass.DoFor<TButton>(procedure (Button: TButton) begin .... end);  // compiles


MyClass.DoFor(procedure (Button: TButton) begin .... end);  // doesn't compile