每次我深入C#项目时,都会遇到很多事件,这些事件实际上只需要传递一个项目。我坚持使用EventHandler/EventArgs的做法,但是我喜欢做的是:

public delegate void EventHandler<T>(object src, EventArgs<T> args);

public class EventArgs<T>: EventArgs {

  private T item;

  public EventArgs(T item) {
    this.item = item;
  }

  public T Item {
    get { return item; }
  }
}

以后我可以拿我的
public event EventHandler<Foo> FooChanged;

public event EventHandler<Bar> BarChanged;

但是,.NET的标准似乎是为每种事件类型创建一个新的委托(delegate)和EventArgs子类。我的通用方法有什么问题吗?

编辑:这篇文章的原因是,我只是在一个新项目中重新创建了这个,并且想确保它没问题。实际上,我在发布时正在重新创建它。我发现有一个通用的EventHandler<TEventArgs>,因此您不需要创建通用的委托(delegate),但是您仍然需要通用的EventArgs<T>类,因为TEventArgs: EventArgs

另一个编辑:内置解决方案的一个缺点(对我而言)是多余的:
public event EventHandler<EventArgs<Foo>> FooChanged;


public event EventHandler<Foo> FooChanged;

不过,对于客户来说,注册事件可能会很痛苦,因为默认情况下会导入System namespace ,因此即使使用像Resharper这样的高级工具,他们也必须手动查找您的 namespace ...任何人都有与此相关的想法?

最佳答案

自.NET Framework 2.0以来,已添加以下形式的代表

public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs

因为您为EventArgs提供了具有单个数据项的现成实现,所以您的方法要走得更远,但是它缺少原始想法的多个属性:
  • 您不能在不更改相关代码的情况下向事件数据添加更多属性。您将必须更改委托(delegate)签名以向事件订阅者提供更多数据。
  • 您的数据对象是通用的,但它也是“匿名的”,在阅读代码时,您将必须从用法中解密“Item”属性。应该根据它提供的数据来命名。
  • 当您具有基础(项目)类型的层次结构时,以这种方式使用泛型,就无法创建EventArgs的并行层次结构。例如。即使BaseType是DerivedType的基础,EventArgs 也不是EventArgs 的基础类型。

  • 因此,我认为最好使用通用EventHandler ,但仍然具有根据数据模型的要求进行组织的自定义EventArgs类。使用Visual Studio和诸如ReSharper之类的扩展,只需几个命令即可创建新的类。

    关于c# - .NET EventHandlers-通用或否?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/129453/

    10-11 22:17