小编典典

event Action<> vs event EventHandler<>

all

event Action<>声明和之间有什么不同吗event EventHandler<>

假设实际上什么对象引发了事件并不重要。

例如:

public event Action<bool, int, Blah> DiagnosticsEvent;

对比

public event EventHandler<DiagnosticsArgs> DiagnosticsEvent;

class DiagnosticsArgs : EventArgs
{
    public DiagnosticsArgs(bool b, int i, Blah bl)
    {...}
    ...
}

在这两种情况下,用法几乎相同:

obj.DiagnosticsEvent += HandleDiagnosticsEvent;

有几件事我不喜欢event EventHandler<>模式:

  • 从 EventArgs 派生的额外类型声明
  • 强制传递对象源——通常没人关心

更多代码意味着需要维护更多代码,但没有任何明显优势。

结果,我更喜欢event Action<>

但是,只有在 Action<> 中有太多类型参数时,才需要一个额外的类。


阅读 57

收藏
2022-08-15

共1个答案

小编典典

基于之前的一些答案,我将把我的答案分为三个方面。

首先,使用Action<T1, T2, T2... >与使用派生类的物理限制EventArgs。有三个:首先,如果您更改参数的数量或类型,则必须更改订阅的每个方法以符合新模式。如果这是第 3 方程序集将使用的面向公众的事件,并且事件 args 有可能发生变化,这将是为了保持一致性而使用从事件 args 派生的自定义类的原因(请记住,您仍然可以use an Action<MyCustomClass>) 其次,usingAction<T1, T2, T2... >将阻止您将反馈传递回调用方法,除非您有某种与 Action 一起传递的对象(例如具有 Handled 属性)。第三,你没有得到命名参数,所以如果你传递 3bool的 an int,两个string‘s 和 a DateTime,你不知道这些值的含义是什么。附带说明一下,您仍然可以使用“在仍在使用时安全地触发此事件的方法Action<T1, T2, T2... >”。

其次,一致性影响。如果您有一个已经在使用的大型系统,那么遵循系统其余部分的设计方式几乎总是更好,除非您有充分的理由不这样做。如果您有需要维护的公开事件,那么替换派生类的能力可能很重要。记在脑子里。

第三,现实生活中的实践,我个人发现我倾向于为需要交互的属性更改(特别是在使用相互交互的视图模型进行 MVVM 时)或事件发生的位置创建很多一次性事件单个参数。大多数情况下,这些事件采用public event Action<[classtype], bool> [PropertyName]Changed;or的形式public event Action SomethingHappened;。在这些情况下,有两个好处。首先,我得到了发行类的类型。如果MyClass声明并且是唯一触发事件的类,我会MyClass在事件处理程序中获得一个显式实例来使用。其次,对于简单的事件,比如属性改变事件,参数的含义是显而易见的,并在事件处理程序的名称中说明,我不必为这类事件创建无数的类。

2022-08-15