附加带有传递参数的方法后分离事件处理程序
本文关键字:方法 分离 事件处理 程序 参数 | 更新日期: 2023-09-27 18:25:45
我需要将一个参数(在C#中)传递给事件处理程序,然后才能分离事件处理程序。
我附加事件处理程序并传递参数:
_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
事件按预期调用。我尝试分离事件处理程序:
_map.MouseLeftButtonUp -= (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
代码执行时没有出现错误,但似乎没有分离。
如果我以更传统的方式(不传递参数)附加事件处理程序:
_map.MouseLeftButtonUp+=_map_MouseLeftButtonUp;
并分离
_map.MouseLeftButtonUp -= _map_MouseLeftButtonUp;
一切正常
通过更传统的方式分离事件处理程序(采用参数)
_map.MouseLeftButtonUp -= _map_MouseLeftButtonUp2;
给我一个错误,说代表不匹配(这是有道理的)
所以我的问题是:当我传递参数时,为什么事件处理程序没有真正分离,有没有办法绕过这个问题。
创建lambda(匿名)函数时,实际上每次都在创建一个新函数。
前两行不起作用的原因是,它们是两个完全不同的函数,恰好做着相同的事情。正确的分离方式是订阅和取消订阅函数,正如您已经了解的那样。
另一种可能不值得的选择是将lambda保存到一个变量中。
Action<object, MouseButtonEventArgs> myEventMethod = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
_map.MouseLeftButtonUp += myEventMethod;
// ...
_map.MouseLeftButtonUp -= myEventMethod;
原因是两个委托不相等:
// You add one delegate instance
_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
// ..And try to remove another one (not previous!) That's why the first delegate remains unremoved
_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
你可以通过说服自己
var x = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
var y = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
if (Object.Equals(x, y)) { // <- You expected this behaviour
...
}
else { // <- Alas, this is a real situation: x != y
...
}
出现这种行为的原因是,当Object.Equals未被重写时(如果是委托,则不是),Object.Equaals的工作方式与Object.ReferenceEquals的工作方式相同,后者检查实例引用(地址)。当然,x和y的地址以及两个您的代理人