由于Delphi中出现匿名方法,我想在VCL组件事件中使用它们.显然,为了向后兼容,VCL没有更新,所以我设法简单的实现一些注意事项.
type TNotifyEventDispatcher = class(TComponent) protected FClosure: TProc<TObject>; procedure OnNotifyEvent(Sender: TObject); public class function Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent; overload; function Attach(Closure: TProc<TObject>): TNotifyEvent; end; implementation class function TNotifyEventDispatcher.Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent; begin Result := TNotifyEventDispatcher.Create(Owner).Attach(Closure) end; function TNotifyEventDispatcher.Attach(Closure: TProc<TObject>): TNotifyEvent; begin FClosure := Closure; Result := Self.OnNotifyEvent end; procedure TNotifyEventDispatcher.OnNotifyEvent(Sender: TObject); begin if Assigned(FClosure) then FClosure(Sender) end; end.
这就是它的用法如何:
procedure TForm1.FormCreate(Sender: TObject); begin Button1.OnClick := TNotifyEventDispatcher.Create(Self,procedure (Sender: TObject) begin Self.Caption := 'DONE!' end) end;
很简单我相信有两个缺点:
>我必须创建一个组件来管理匿名方法的生命周期(我浪费了更多的内存,这对间接性来说有点慢),我仍然希望在我的应用程序中更清晰的代码)
>我必须为每个事件签名实现一个新类(非常简单).这一个有点复杂,VCL仍然有非常常见的事件签名,对于每一个特殊情况,当我创建这个类时,它永远是完成的.
你觉得这个实现是什么?有什么可以使它更好吗?
解决方法
你可以看看我的
multicast event implementation in DSharp.
那么你可以这样编写代码:
function NotifyEvent(Owner: TComponent; Delegates: array of TProc<TObject>): TNotifyEvent; overload; begin Result := TEventHandler<TNotifyEvent>.Create<TProc<TObject>>(Owner,Delegates).Invoke; end; function NotifyEvent(Owner: TComponent; Delegate: TProc<TObject>): TNotifyEvent; overload; begin Result := NotifyEvent(Owner,[Delegate]); end; procedure TForm1.FormCreate(Sender: TObject); begin Button1.OnClick := NotifyEvent(Button1,[ procedure(Sender: TObject) begin Caption := 'Started'; end,procedure(Sender: TObject) begin if MessageDlg('Continue?',mtConfirmation,mbYesNo,0) <> mrYes then begin Caption := 'Canceled'; Abort; end; end,procedure(Sender: TObject) begin Caption := 'Finished'; end]); end;