使用“发件人”与自定义EventArgs

考虑这种情况。 我有一个对象,让我们叫它...... Foo。 Foo提出了一个名为“Loaded”的简单事件。 作为事件信息的一部分,消费者需要知道哪个foo对象引发了事件。 我们的团队采用了以下模式。

1)创建一个从EventArgs继承的新类 - 例如,FooEventArgs:System.EventArgs。

2)将Foo类型的属性添加到FooEventArgs中,通过构造函数传入该属性。

3)使用通用版本的EventHandler声明事件,所以

public event EventHandler<FooEventArgs> Loaded;

4)使用以下签名从Foo类中提起事件:

Loaded(this, new FooEventArgs(this));

基本上,它所做的是使“发件人”成为foo对象,但它也将foo对象引用作为强类型属性放入事件参数中。

这样做的一个好处是,在处理事件时,没有人不得不投入“发件人”,这会降低事件消费者与事件提升者之间的耦合度。 另一个“优点”是,如果事件提升者的类型必须改变,并且因此强类型属性(希望永不会发生),那么不是简单地在代码开始失败时抛出它为空, API实际上会中断,因此它可以在编译时修复。

对我而言,这种模式看起来好像可能是矫枉过正。 他们是否应该更多地信任“sender”参数,并且抛弃自定义事件参数? 我的团队认为没有人真的使用sender参数。 传递引发事件的对象的最佳做法是什么?

编辑:到目前为止,很好的反馈意见,我会保留这个开放的另一天左右,然后我接受一个。


常见模式是使用发件人,而不是将发件人单独添加到EventArgs。 自定义EventArgs用于其他状态,如树事件的树节点,可取消事件的(可设置)布尔值等。

我们使用通用模式,因为BCL类也使用它,并且为“自制事件”做出改变可能会造成混淆。 另外,我们有一个全局的IoC发布者 - 订阅者模式,但是这个模式只能用于正常的EventHandler委托签名,因为这些类型事先并不知道。 在这种情况下,无论如何都需要强制转换(例如对于自定义EventArgs),所以我们可能也会发送该发送者。


我不认为这是矫枉过正。 我同意你有一个独立的FooEventArgs类的优点。 这样做的另一个好处是,如果将来需要向事件添加更多信息,则可以将更多属性添加到FooEventArgs中,并且不需要更改委托。


我会说你删除EventArgs的子类并使用sender属性来标识事件的发件人。 我认为遵循惯例的论点具有优点,但EventArgs中的参数不是必需的。 我个人会放弃它,只使用sender属性。

如果你想把它作为一个强类型传递,你也可以创建一个自定义委托来用于你的事件...

public delegate void LoadedHandler(FooEventArgs args);

这样你就可以把它作为一个强大的类型......重复使用委托很棒,但如果它们不适合你正在尝试做的事情,那么你不应该仅仅使用内置的委托。

链接地址: http://www.djcxy.com/p/54051.html

上一篇: using "sender" vs. custom EventArgs

下一篇: Unit testing that an event is raised in C#