题
这个问题在这里已经有一个答案:
- 在C#中取消订阅的匿名方法 11个答案
我多次使用Resharper 5.1代码分析,我从Resmanper中收到评论
“通过匿名代表取消订阅的事件”
#Part of Code
if (((bool)e.NewValue))
{
listView.PreviewTextInput += (o,args) =>
listView_PreviewTextInput(o,args,listView);
}
else
{
listView.PreviewTextInput -= (o, args) =>
listView_PreviewTextInput(o, args, listView);
}
我如何纠正或最佳
解决方案
您可以将LAMDBA提取到一个变量:
EventHandler func = (sender, e) =>
listView_PreviewTextInput(sender, e, listView);
if (((bool)e.NewValue))
{
listView.PreviewTextInput += func;
}
else
{
listView.PreviewTextInput -= func;
}
其他提示
警告!接受的答案 来自史蒂文是 错误的, ,它所做的只是掩盖了Resmater警告的问题。
每次执行给定代码
EventHandler func = (sender, e) =>
listView_PreviewTextInput(sender, e, listView);
你会得到一个新的(因为您可能会捕获不同的 listView
)匿名代表的实例保存到 func
, ,一个尚未订阅任何事件的实例,因此依次此代码
listView.PreviewTextInput -= func;
由于您无法订阅未订阅的事件,因此无能为力。这将导致令人难以置信的错误,例如事件处理程序“两次”,内存泄漏等。
实际上,乔恩·斯基特(Jon Skeet)说了 在某些情况下可能有效:
C#规范明确指出(IIRC),如果您有两个匿名函数(匿名方法或lambda表达式) 可以不可以 从该代码创建平等的委托。
例如,当编译器每次都不会生成新实例时,您会看到不错的行为。
但这是不可靠的,在起动问题中描述的情况下肯定不会起作用 listView
.
所以我的建议是:
仅当您永远不必退订时,才会使用匿名功能作为事件处理程序。
不隶属于 StackOverflow