将变量捕获到EventHandler中
我可能会稍微过度思考这一点,但我可以帮助确定一种方法/最好的方法来做到以下几点。
我有一个事件处理程序附加到一个对象,该对象是另一个类的属性。在我的事件处理程序中,我需要有关导致事件的对象的其他元数据(即包含它的对象的ID)。从发件人和事件信息中无法获得我需要的信息。我倾向于这是一个使用捕获变量的好地方,但我不确定我的实现想法。
所以为了在代码中说明我有一个事件处理程序:
void MyEventHandler(object sender, EventArgs e){
//Do Stuff here
}
(作为一个注释,我在这里使用基本的EventArgs,但在我的实际实现中,它是一个专门的子类,并使用通用的EventHandler声明事件)
我目前正在附加它:
topObject.SubObject.EventToHandle += MyEventHandler;
我后来像这样解决它:
topObject.SubObject.EventToHandle -= MyEventHandler;
我在处理事件时想要topObject的ID,所以我要更改MyEventHandler以获得以下签名:
void MyEventHandler(int id, object sender, EventArgs e)
并附加事件处理程序,如下所示:
topObject.SubObject.EventToHandle += (s,e) => MyEventHandler(topObject.ID, s,e);
我对此的关注是双重的。
一旦我在附加函数之外,处理程序实际上会在没有删除的情况下消失的范围是否存在问题。我曾经看到过一些奇怪的错误,当我使用lambda表达式时,事件处理程序在我身上消失了。它不是所有的时间,只是在某些情况下。任何人都可以告诉我这些情况可能是什么,所以我知道什么时候可以安全使用我的语法。
我记不清楚但是如果我使用这种语法,我认为我不能删除事件处理程序,因为创建的隐式对象不一样。
由于这两个问题,我的想法是创建一个Action并保存动作并使用它直到我需要删除事件处理程序。我做了以下事情:
Action<object, EventArgs> handler = (s,e) => MyEventHandler(topObject.ID, s,e);
topObject.SubObject.EventToHandle += handler;
我知道该动作无法转换为事件处理程序。是否有一些简单的方法可以进行此转换,仍然可以确保我可以分离事件处理程序?我只是在想这个/有没有一种方法我现在没有看到这样做?
没有找到相关结果
已邀请:
4 个回复
乐遣杀屎
暑袜眠退
要么
在这种情况下,调用者会执行以下类型的代码:
并像这样实现OnSubObjectMyEvent(示例):
这里我假设SubObject有一个TopObject属性,允许我获取顶级对象的id。 这就是大多数.NET Framework类的工作方式。这种方法有什么问题吗?
粳饶瓢部
我会在发送者和args的约定中保留事件签名。
逝媳蘑贩茄
的事件。实际上,对于违反此签名的事件,存在一个FxCop规则,CA1009:正确声明事件处理程序: 事件处理程序方法有两个 参数。第一种是类型 System.Object并命名为'sender'。 这是提出的对象 事件。第二个参数是类型 System.EventArgs并命名为'e'。 有几种解决方案(替代方案): 将topObject.ID作为自定义EventArgs的成员传递。 创建一个封装topObject.ID的包装器对象,并将事件处理程序挂钩到此对象的方法。 使用一个闭包范围,该范围可以保留对范围内topObject.ID的引用(这与上面的方法相同,但重量提升是由编译器完成的)