将委托实例添加到Component.Events(EventHandlerList)有什么好处?

Tom*_*Tom 7 c# winforms

在从类组件派生的类中,我有时会看到声明的事件:

private static readonly object LoadEvent = new object();
public event EventHandler<MyEventArgs> Load
{
    add { Events.AddHandler(LoadEvent, value); }
    remove { Events.RemoveHandler(LoadEvent, value); }
}

protected virtual void OnLoad(MyEventArg e)
{
    var evnt = (EventHandler<MyEventArg>)Events[LoadEvent];
    if (evnt != null) 
        evnt(this, e);
}
Run Code Online (Sandbox Code Playgroud)

而不仅仅是:

public event EventHandler<MyEventArgs> Load;

protected virtual void OnLoad(MyEvent e)
{
   if (Load != null)
       Load(this, e);
}
Run Code Online (Sandbox Code Playgroud)

我很想重构使用更短的方法,但是如果使用我缺少的Component EventHanderList有一些优点,我会犹豫不决.

我目前可以想到的唯一优势是:

  • 处理组件时,将删除EventHandlerList中的所有项,从而有效地自动解除事件处理程序.
  • 由于所有附加的委托进入单个EventHandlerList,可能会减少内存碎片.

还有别的事吗?

(这不是关于事件中显式添加+删除的一般用法的问题.)

Mar*_*ell 9

这对稀疏事件很有用.UI控件往往有数十个(有时超过100个)事件.如果每个事件都使用了类似字段的事件,那么每个事件都需要一个引用后备字段.使用100个事件,即x86上的400个字节或x64上的800个字节,即使没有订阅单个事件.

例如,在您添加任何内容之前,winforms System.Windows.Forms.Form有91个事件.每个实例至少有 69个.Control

所以; 一个带有几个标签,输入框和按钮的窗体可以很容易地有一个额外的2000个参考字段(x86上的16k),其中大多数都没有做任何事情.

EventHandlerList本质上是一种键/值查找,这意味着如果只有3个事件订阅(我想"点击"和其他人也许一些),那么只需要记忆的面值.