在订阅了另一个对象的事件的委托中使用 (object sender)
Posted
技术标签:
【中文标题】在订阅了另一个对象的事件的委托中使用 (object sender)【英文标题】:Using (object sender) in a delegate subscribed to an event of another object 【发布时间】:2013-08-25 18:41:35 【问题描述】:假设我有 2 个类,A 类和 B 类。对象 A(属于 A 类)包含一些对象 B(属于 B 类)。 B 对象有一个事件,并且对象 A 订阅了一个委托,该委托在(任何这些 B 对象的)事件被引发时执行。
private void fooEventHandler(object sender, EventArgs e)
...
在 fooEventHandler 中执行某些操作后(必须在 A 中完成),我想向引发事件的 B 对象发出我在 fooEventHandler 中所做的结果的信号。所以我做了以下事情:
private void fooEventHandler(object sender, EventArgs e)
...
if (allOK)
((classB)sender).isOK();
else
((classB) sender).isNotOK();
所以我实际上是在事件发生后使用发送方调用 objectB 上的特定方法。我这样做是为了避免将一些从设计角度来看不应该在 objectB 中的 objectA 成员传递给 objectB(在他的构造函数中)。这是处理问题的合理方法吗?这种方式使用(object sender)是否常见?
【问题讨论】:
isNotOK()。以 CancelEventHandler 委托为例。 嗯..你可以更具体一点吗?我正在查看 CancelEventHandler 但我不明白你的意思... 如果是你的事件,最好定义一个以 classB 作为参数而不是对象的处理程序 不错的建议 Vadim,但微软的最佳实践不是建议每个事件处理程序方法都有一个签名,如 (object sender someEventargs e)?无论如何,除此之外,我的代码还可以吗?仍然想知道 Hans Passant 是什么意思…… 【参考方案1】:我认为你让你的 A 类与你的 B 类太耦合了。如果在处理事件后您需要 A 做的就是调用某个回调 - 然后传递回调。这样,您可以传递例如 lambda 表达式,或传递与 B 或其他相关的类的方法。
所以-
private void fooEventHandler(Action p_okCallback, Action p_notOkCallback)
...
if (allOK)
p_okCallback();
else
p_notOkCallback();
或 -
private void fooEventHandler(Action<bool> p_callback)
...
p_callback(allOk);
如果事件不在你的控制之下,你可以按照 Helmer 的建议和从 EventArgs 继承。但同样 - 我会传入回调,而不是类本身。
另一种选择 - 如果您觉得需要多个方法并且对传递十几个回调感到尴尬 - 考虑使用您需要的方法传递一个接口。
【讨论】:
【参考方案2】:这是一个解决方案,但我认为这不是更好的方法。
这是另一个解决方案
第 1 步: - 创建一个 EventArgs 的继承类,并在其上添加一些属性,这些属性定义要在 B 类中执行的处理
示例:
public class ClassBEventArgs : EventArgs
bool treatmentIsOK = false;
第 2 步: 在 Class B 的同一个命名空间中创建一个新的 Delegate Event 定义并使用它来声明事件
示例:
namespace ClassBNameSpace
public delagate fooEventHandlerDelegate void (object sender, ClassBEventArgs e);
public ClassB
public event fooEventHandlerDelegate fooEventHandler;
.........
第三步: 在 ClassB 中,使用 ClassBEventArgs 对象引发 fooEventHandler 事件。 在 ClassA 事件处理程序中设置treatmentIsOK EventArgs 的正确值。当事件从ClassA回调到ClassB时,可以利用treatmentIsOK属性的值
样品:
.......
if (this.fooEventHandler != null)
ClassBEventArgs customEventArgs = new ClassBEventArgs();
this.fooEventHandler (this,customEventArgs);
if (customEventArgs.treatmentIsOK )
this.isOK(); ==> Your code
else
this.isOK(); ==> Your code
.......
【讨论】:
这是@Hans 在对该问题的第一条评论中所说的。使用CancelEventArgs
可以轻松完成,不是吗?为什么不使用CancelEventArgs
当然!!你可以使用它。我的解决方案提供了更精细地自定义 EventArgs 的可能性。
仅供以后使用。 CancelEventArgs 是一个很好的解决方案
很好,我不知道您可以在触发事件后检查自定义 eventArg 成员的值。 (我已经在使用自定义事件处理程序,我没有将它放在示例中,因为我认为它只是分散了手头的主题,显然不是)。谢谢,我刚刚实现了您的想法,在编写其他部分之后我将能够对其进行真正的测试,但我现在仍将其标记为解决方案 =)【参考方案3】:
为什么不创建自己的 EventArgs 类并将 B 放入其中?
喜欢:
public class ClassBEventArgs : EventArgs
public classB classBObject get; set;
【讨论】:
以上是关于在订阅了另一个对象的事件的委托中使用 (object sender)的主要内容,如果未能解决你的问题,请参考以下文章