我可以在事件处理程序上使用闭包(即TButton OnClick)

Maj*_*agu 14 delphi delphi-2009

如果我尝试在事件处理程序上使用闭包,编译器会抱怨:

不兼容的类型:"方法指针和常规过程"

我理解..但有没有办法在方法指针上使用clouser?以及如何定义是否可以?

例如:

Button1.Onclick = procedure( sender : tobject ) begin ... end;
Run Code Online (Sandbox Code Playgroud)

谢谢!

小智 10

@Button1.OnClick := pPointer(Cardinal(pPointer( procedure (sender: tObject) 
begin 
  ((sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!' 

end )^ ) + $0C)^;
Run Code Online (Sandbox Code Playgroud)

适用于Delphi 2010

  • 此解决方案适用于 Win32 平台,但不适用于 Win64。 (2认同)

Han*_*ric 5

一个很好的问题.

据我所知,在当前版本的Delphi中不可能做到.这非常不幸,因为这些匿名过程对于快速设置对象的事件处理程序非常有用,例如在xUnit类型的自动测试框架中设置测试夹具时.

CodeGear应该有两种方法来实现此功能:

1:允许创建匿名方法.像这样的东西:

Button1.OnClick := procedure( sender : tobject ) of object begin
  ...
end;
Run Code Online (Sandbox Code Playgroud)

这里的问题是作为匿名方法的自指针放置的内容.可以使用创建匿名方法的对象的self指针,但是只能从对象上下文创建匿名方法.更好的想法可能是在幕后创建一个虚拟对象以包含匿名方法.

2:或者,可以允许事件类型接受方法和过程,只要它们共享定义的签名即可.这样您就可以按照自己的方式创建事件处理程序:

Button1.OnClick := procedure( sender : tobject ) begin
  ...
end;
Run Code Online (Sandbox Code Playgroud)

在我看来,这是最好的解决方案.