当前位置:  开发笔记 > 编程语言 > 正文

.NET EventHandlers - 通用还是不通用?

如何解决《.NETEventHandlers-通用还是不通用?》经验,为你挑选了3个好方法。

每次我深入开始一个C#项目时,我最终都会遇到许多事件,这些事件实际上只需要传递一个项目.我坚持EventHandler/ EventArgs练习,但我喜欢做的事情是这样的:

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

public class EventArgs: EventArgs {

  private T item;

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

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

后来,我可以拥有我的

public event EventHandler FooChanged;

public event EventHandler BarChanged;

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


编辑:这篇文章的原因是我刚刚在一个新项目中重新创建了它,并希望确保它没问题.实际上,我在发布时正在重新创建它.我发现有一个泛型EventHandler,所以你不需要创建泛型委托,但是你仍然需要泛型EventArgs类,因为TEventArgs: EventArgs.
另一个编辑:内置解决方案的一个缺点(对我而言)是额外的冗长:

public event EventHandler> FooChanged;

public event EventHandler FooChanged;

但是客户注册你的事件可能会很麻烦,因为系统命名空间是默认导入的,因此他们必须手动寻找你的命名空间,即使使用像Resharper这样的花哨工具......任何人都有任何与此有关的想法?



1> Ilya Ryzhenk..:

自.NET Framework 2.0以来,已添加以下表单的委托

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

您的方法更进一步,因为您为具有单个数据项的EventArgs提供了开箱即用的实现,但它缺少原始想法的几个属性:

    您无法在不更改相关代码的情况下向事件数据添加更多属性.您必须更改委托签名以向事件订阅者提供更多数据.

    您的数据对象是通用的,但它也是"匿名的",在阅读代码时,您必须从用法中解读"Item"属性.它应该根据它提供的数据命名.

    通过这种方式使用泛型,当您具有底层(项)类型的层次结构时,您无法建立EventArgs的并行层次结构.例如,EventArgs 不是EventArgs 的基本类型,即使BaseType是DerivedType的基础.

所以,我认为最好使用通用的EventHandler ,但仍然有自定义的EventArgs类,根据数据模型的要求进行组织.使用Visual Studio和ReSharper之类的扩展,创建新类只需要很少的命令.



2> Ryan Lundy..:

为了使通用事件声明更容易,我为它创建了几个代码片段.要使用它们:

复制整个代码段.

将其粘贴到文本文件中(例如,在记事本中).

使用.snippet扩展名保存文件.

将.snippet文件放在相应的代码段目录中,例如:

Visual Studio 2008\Code Snippets\Visual C#\ My Code Snippets

这是一个使用自定义EventArgs类和一个属性的类:



  
    
Generic event with one type/argument. ev1Generic Code snippet for event handler and On method Ryan Lundy Expansion
type Type of the property in the EventArgs subclass. propertyType argName Name of the argument in the EventArgs subclass constructor. propertyName propertyName Name of the property in the EventArgs subclass. PropertyName eventName Name of the event NameOfEvent $eventName$; protected virtual void On$eventName$($eventName$EventArgs e) { var handler = $eventName$; if (handler != null) handler(this, e); }]]> System

这是一个有两个属性的:



  
    
Generic event with two types/arguments. ev2Generic Code snippet for event handler and On method Ryan Lundy Expansion
type1 Type of the first property in the EventArgs subclass. propertyType1 arg1Name Name of the first argument in the EventArgs subclass constructor. property1Name property1Name Name of the first property in the EventArgs subclass. Property1Name type2 Type of the second property in the EventArgs subclass. propertyType1 arg2Name Name of the second argument in the EventArgs subclass constructor. property1Name property2Name Name of the second property in the EventArgs subclass. Property2Name eventName Name of the event NameOfEvent $eventName$; protected virtual void On$eventName$($eventName$EventArgs e) { var handler = $eventName$; if (handler != null) handler(this, e); }]]> System

您可以按照模式使用任意数量的属性创建它们.



3> swilliams..:

不,我不认为这是错误的做法.我认为它甚至可以在[精彩]书籍框架设计指南中推荐.我做同样的事情.

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有