VCL events with anonymous methods - what do you think about this implementation?

為{幸葍}努か 提交于 2019-11-30 11:29:11

You can take a look at my multicast event implementation in 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;

You could make TNotifyEventDispatcher to be a subclass of TInterfacedObject so you do not need to care about freeing it.

But to be more pragmatic one would use traditional event assignment that takes less lines of code and is supported by the IDE.

Interesting approach.

(Disclaimer: haven't checked this, but it is something to investigate): You may have to be careful though about what goes on in capturing the state of the method that "assigns" the anonymous method to the event. Capturing can be an advantage but can also have side effects you do not want. If your anonymous method needs info about the form at the time it is fired, it may end up with info at the time of its assignment. Update: apparently this is not the case, see comment by Stefan Glienke.

You do not really need different classes. Using overloading you could create different class Create functions that each take a specific signature and return the corresponding event handler and the compiler will sort it out.

Managing lifetime could be simplified if you derived from TInterfacedObject instead of TComponent. Reference counting should then take care of destroying the instance when it is no longer used by the form. Update: this does require keeping a reference to the instance somewhere in the form, or refcounting won't help as the instance will be freed immediately after assigning the notify event. You could add an extra parameter on the class Create functions to which you pass a method that the instance can useto add itself to some list of the form.

Side note: All in all though I have to agree with David in his comment on the question: it does sound like a lot of work for the "sole purpose" of using anonymous methods...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!