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

标签 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);
}

不仅仅是:

public event EventHandler<MyEventArgs> Load;

protected virtual void OnLoad(MyEvent e)
{
   if (Load != null)
       Load(this, e);
}

我很想重构以使用更短的方法,但我很犹豫,以防使用我缺少的组件 EventHanderList 有一些优势。

目前我能想到的优点只有:

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

还有什么吗?

(这不是关于在事件上显式添加和删除的一般用途的问题。)

最佳答案

这对稀疏 事件很有用。 UI 控件往往有几十个(有时超过 100 个)事件。如果为每个事件使用一个类似字段的事件,则每个事件 都需要一个引用支持字段。对于 100 个事件,即在 x86 上为 400 字节或在 x64 上为 800 字节,即使没有订阅一个事件

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

所以;带有几个标签、输入框和按钮的窗口窗体很容易有额外的 2000 个引用字段(在 x86 上为 16k)其中大部分什么都不做

EventHandlerList 本质上是一个键/值查找,这意味着如果只订阅了 3 个事件(我想是“点击”,也许还有其他一些),那么只有名义上的内存量是必需的。

关于c# - 将委托(delegate)实例添加到 Component.Events (EventHandlerList) 有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11895971/

相关文章:

c# - 删除 GDI+ 对象

c# - 复选框数据绑定(bind)默认值 null

c# - GC 会清理非事件但在范围内的引用所引用的对象吗?

c# - 将 Windows 窗体 TreeView 项关联到实际数据

c# - 关于类的属性更改时如何使 UI 使用react的任何想法?

c# - 在后台 worker 错误中更改标签文本

c# - 如何将事件处理程序添加到 DataGrid 按钮(该按钮是基于数据库动态添加的)?

c# - 获取 IP 地址 WPF 和 C# 显示问题

c# - 防止反序列化 DateTime 值时进行时区转换

c# - 我如何在 C# 窗口存储应用程序中使用键移动图像