使用匿名方法的VCL事件 - 您对此实现有什么看法? [英] VCL events with anonymous methods - what do you think about this implementation?

查看:221
本文介绍了使用匿名方法的VCL事件 - 您对此实现有什么看法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于Delphi中出现匿名方法,我想在VCL组件事件中使用它们。显然,为了向后兼容,VCL没有更新,所以我设法简单的实现一些注意事项。

Since anonymous methods appeared in Delphi I wanted to use them in VCL components events. Obviously for backward compatibility the VCL wasn't updated, so I managed to make a simple implementation with a few caveats.

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.

这是如何使用的,例如:

And this is how it's used for example:

procedure TForm1.FormCreate(Sender: TObject);
begin    
  Button1.OnClick := TNotifyEventDispatcher.Create(Self,
    procedure (Sender: TObject)
    begin
      Self.Caption := 'DONE!'
    end)
end;

很简单我相信有两个缺点:

Very simple I believe, there are two drawbacks:


  • 我必须创建一个组件来管理匿名方法的生命周期(我浪费了更多的内存,这对间接性有点慢,但我更喜欢更多在我的应用程序中清除代码)

  • I have to create a component to manage the lifetime of the anonymous method (I waste a bit more of memory, and it's a bit slower for the indirection, still I prefer more clear code in my applications)

我必须为每个事件签名实现一个新类(非常简单)。这个有点复杂,但VCL仍然有非常常见的事件签名,对于每一个特殊情况,我创建了这个类,它永远都是这样。

I have to implement a new class (very simple) for every event signature. This one is a bit more complicated, still the VCL has very common event signatures, and for every special case when I create the class it's done forever.

你对这个实现有什么看法?有什么可以让它更好?

What do you think of this implementation? Something to make it better?

推荐答案

你可以看看我的 DSharp中的多播事件实现

然后你可以编写这样的代码:

Then you can write code like this:

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;

这篇关于使用匿名方法的VCL事件 - 您对此实现有什么看法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆