问题描述
每次我开始深入研究 C# 项目时,我都会遇到很多实际上只需要传递一个项目的事件.我坚持 EventHandler
/EventArgs
实践,但我喜欢做的是:
Every time I start in deep in a C# project, I end up with lots of events that really just need to pass a single item. I stick with the EventHandler
/EventArgs
practice, but what I like to do is have something like:
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 的标准是为每种类型的事件创建一个新的委托和 EventArgs
子类.我的通用方法有问题吗?
这篇文章的原因是我刚刚在一个新项目中重新创建了它,并想确保它没问题.实际上,我在发布时正在重新创建它.我发现有一个通用的
EventHandler
,所以你不需要创建通用的委托,但你仍然需要通用的EventArgs
类,因为 TEventArgs: EventArgs
.另一个内置解决方案的一个缺点(对我来说)是额外的冗长:
However, it seems that the standard for .NET is to create a new delegate and EventArgs
subclass for each type of event. Is there something wrong with my generic approach?
The reason for this post is that I just re-created this in a new project, and wanted to make sure it was ok. Actually, I was re-creating it as I posted. I found that there is a generic
EventHandler<TEventArgs>
, so you don't need to create the generic delegate, but you still need the generic EventArgs<T>
class, because TEventArgs: EventArgs
.Another One downside (to me) of the built-in solution is the extra verbosity:
public event EventHandler<EventArgs<Foo>> FooChanged;
对比
public event EventHandler<Foo> FooChanged;
客户注册您的事件可能会很痛苦,因为 System 命名空间是默认导入的,所以他们必须手动寻找您的命名空间,即使使用像 Resharper 这样的花哨工具......任何人都有任何想法与此有关吗?
It can be a pain for clients to register for your events though, because the System namespace is imported by default, so they have to manually seek out your namespace, even with a fancy tool like Resharper... Anyone have any ideas pertaining to that?
推荐答案
自 .NET Framework 2.0 起添加了以下形式的委托
Delegate of the following form has been added since .NET Framework 2.0
public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs
您的方法更进一步,因为您为具有单个数据项的 EventArgs 提供了开箱即用的实现,但它缺少原始想法的几个属性:
You approach goes a bit further, since you provide out-of-the-box implementation for EventArgs with single data item, but it lacks several properties of the original idea:
- 您无法在不更改相关代码的情况下向事件数据添加更多属性.您将不得不更改委托签名以向事件订阅者提供更多数据.
- 您的数据对象是通用的,但它也是匿名的",在阅读代码时,您必须从用法中破译Item"属性.它应该根据它提供的数据命名.
- 以这种方式使用泛型,当您具有底层(项目)类型的层次结构时,您无法创建 EventArgs 的并行层次结构.例如.EventArgs不是 EventArgs 的基本类型,即使 BaseType 是 DerivedType 的基本类型.
所以,我认为最好使用通用的 EventHandler,但仍然有自定义的 EventArgs 类,根据数据模型的要求进行组织.使用 Visual Studio 和 ReSharper 等扩展,创建这样的新类只需几个命令.
So, I think it is better to use generic EventHandler<T>, but still have custom EventArgs classes, organized according to the requirements of the data model. With Visual Studio and extensions like ReSharper, it is only a matter of few commands to create new class like that.
这篇关于.NET EventHandlers - 通用还是不通用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!