事件增强

Event Enhancement

我正在设法减少我们的事件处理程序占用的行数。集成添加{}和删除{}的最佳方式是什么,这样我就不必每次创建新事件时都重复它。

  public delegate void ErrorEventHandler(System.Object sender);
  protected ErrorEventHandler ErrorEvent;

  public event ErrorEventHandler Error
  {
     add
     {
        ErrorEvent = (ErrorEventHandler)System.Delegate.Combine(ErrorEvent, value);
     }
     remove
     {
        ErrorEvent = (ErrorEventHandler)System.Delegate.Remove(ErrorEvent, value);
     }
  }

感谢 @madreflection 代码现在看起来像这样

public delegate void ErrorEventHandler(System.Object sender);
public event ErrorEventHandler Error;
protected virtual void OnError(object sender) => Error?.Invoke(sender);

这是一个极其冗长的事件定义。

+=-= 运算符对于 Delegate.CombineDelegate.Remove 是 shorthand,另外你可以把 addremove 每个访问器都在一行上。这将节省您一些打字和几行代码。

add { ErrorEvent += value; }

由于您没有使用处理程序集合(例如 System.ComponentModel.Component 中的 Events 属性),因此实际上没有必要实现 addremove 访问者自己。

支持字段不应为 protected。实现事件的 class 应该控制事件的使用方式。

每个事件都可以减少到两行(如果您为每个事件定义一个委托类型,则可以减少到三行,但您不必这样做):

public event ErrorEventHandler Error;
protected virtual void OnError(object sender) => Error?.Invoke(sender);

第一行是一个自动执行的事件。它为事件创建一个私有支持字段,class 中对事件的所有引用都直接使用该字段。它还创建了一个 public 事件成员,消费者可以使用该成员来订阅事件。这包括 add/remove 与您所拥有的相同的逻辑。

OnError 方法(On" + 事件名称)使派生的 classes 能够触发事件而无需使用支持字段(因为它是私有的)并封装空检查逻辑。它是 protected virtual 以便派生 classes 可以覆盖它并在调用基本实现之前插入逻辑(例如日志记录)。 感谢@Markus Safar 指出原因。