通过匿名代理进行事件取消订阅
这个问题在这里已经有了答案:
你可以将lamdba提取到一个变量中:
EventHandler func = (sender, e) =>
listView_PreviewTextInput(sender, e, listView);
if (((bool)e.NewValue))
{
listView.PreviewTextInput += func;
}
else
{
listView.PreviewTextInput -= func;
}
警告! 从Steven接受的答案是错误的 ,它所做的只是掩盖了resharper警告的问题。
每次给定的代码被执行
EventHandler func = (sender, e) =>
listView_PreviewTextInput(sender, e, listView);
你会得到一个全新的(因为你可能捕获不同的listView
)匿名委托的实例保存为func
,一个尚未订阅任何事件的实例,所以这个代码
listView.PreviewTextInput -= func;
将无效,因为您无法退订您未订阅的活动。 这将导致令人难以置信的错误,例如事件处理程序“两次调用”,内存泄漏等。
事实上,乔恩Skeet说它可能在某些情况下工作:
C#规范明确指出(IIRC)如果您有两个匿名函数(匿名方法或lambda表达式),它可能会或可能不会从该代码创建相同的委托。
例如,当编译器每次都不会生成新的实例时,您会看到很好的行为。
但这并不可靠,并且在使用捕获的变量listView
进行初始问题描述的情况下肯定不起作用。
所以我的建议是:
只有在不需要退订的情况下,才可以使用匿名函数作为事件处理程序。
链接地址: http://www.djcxy.com/p/51439.html