delphi - 具有匿名方法的 VCL 事件 - 您对此实现有何看法?

标签 delphi vcl anonymous-methods

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

type
  TNotifyEventDispatcher = class(TComponent)
  protected
    FClosure: TProc<TObject>;

    procedure OnNotifyEvent(Sender: TObject);
  public
    class function Create(Owner: TComponent; const Closure: TProc<TObject>): TNotifyEvent; overload;

    function Attach(const Closure: TProc<TObject>): TNotifyEvent;
  end;

implementation

class function TNotifyEventDispatcher.Create(Owner: TComponent; const Closure: TProc<TObject>): TNotifyEvent;
begin
  Result := TNotifyEventDispatcher.Create(Owner).Attach(Closure)
end;

function TNotifyEventDispatcher.Attach(const 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; const Delegates: array of TProc<TObject>): TNotifyEvent; overload;
begin
  Result := TEventHandler<TNotifyEvent>.Create<TProc<TObject>>(Owner, Delegates).Invoke;
end;

function NotifyEvent(Owner: TComponent; const 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;

关于delphi - 具有匿名方法的 VCL 事件 - 您对此实现有何看法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8025481/

相关文章:

c# - C# 中的匿名方法可以调用自身吗?

delphi - dxComponentPrinter1 的奇怪问题

delphi - TabSheet不显示图像

string - 这种使用 thread var 线程安全吗?

c++ - IStorage 的 VCL 替代品

.net - Delphi vcl.net应用及反编译

delphi - 在传递给另一个函数的匿名方法中使用开放数组参数时出现“无法捕获符号”错误

vb.net - 使用 vb.net Action(Of T) 和 lambda 声明匿名方法时出现问题

delphi - 在delphi中访问其他.exe数据的最简单方法是什么?

delphi - 尽管输出文件为 "smooth",但在渲染 DirectShow 过滤器期间出现卡顿