每次我深入开始一个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 EventHandlerFooChanged; public event EventHandler BarChanged;
但是,似乎.NET的标准是EventArgs
为每种类型的事件创建一个新的委托和子类.我的通用方法有问题吗?
EventHandler
,所以你不需要创建泛型委托,但是你仍然需要泛型EventArgs
类,因为TEventArgs: EventArgs
.
public event EventHandler> FooChanged;
与
public event EventHandlerFooChanged;
但是客户注册你的事件可能会很麻烦,因为系统命名空间是默认导入的,因此他们必须手动寻找你的命名空间,即使使用像Resharper这样的花哨工具......任何人都有任何与此有关的想法?
自.NET Framework 2.0以来,已添加以下表单的委托
public delegate void EventHandler(object sender, TArgs args) where TArgs : EventArgs
您的方法更进一步,因为您为具有单个数据项的EventArgs提供了开箱即用的实现,但它缺少原始想法的几个属性:
您无法在不更改相关代码的情况下向事件数据添加更多属性.您必须更改委托签名以向事件订阅者提供更多数据.
您的数据对象是通用的,但它也是"匿名的",在阅读代码时,您必须从用法中解读"Item"属性.它应该根据它提供的数据命名.
通过这种方式使用泛型,当您具有底层(项)类型的层次结构时,您无法建立EventArgs的并行层次结构.例如,EventArgs
所以,我认为最好使用通用的EventHandler
为了使通用事件声明更容易,我为它创建了几个代码片段.要使用它们:
复制整个代码段.
将其粘贴到文本文件中(例如,在记事本中).
使用.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
您可以按照模式使用任意数量的属性创建它们.
不,我不认为这是错误的做法.我认为它甚至可以在[精彩]书籍框架设计指南中推荐.我做同样的事情.