我尝试将一个EventHandler作为密钥存储到ConditionalWeakTable中,但如果我尝试访问该值,则无法找到它。
var eventReceiver = new StateChangedEventReceiver();
var dict = new ConditionalWeakTable<EventHandler<EventArgs>, string>();
dict.Add(eventReceiver.OnStateChanged, "Foobar");
string dummy;
dict.TryGetValue(eventReceiver.OnStateChanged, out dummy); // returns false!!!
StateChangedEventReceiver的代码如下所示:
public class StateChangedEventReceiver
{
public void OnStateChanged(object sender, EventArgs args)
{
}
}
我使用字典测试了相同的行为,它按预期工作:
var eventReceiver = new StateChangedEventReceiver();
var dict = new Dictionary<EventHandler<EventArgs>, string>();
dict.Add(eventReceiver.OnStateChanged, "Foobar");
string dummy;
dict.TryGetValue(eventReceiver.OnStateChanged, out dummy); // returns true -> as expected
为什么?
没有ConditionalWeakTable的构造函数需要比较器。我尝试从.Net 4.5到.Net 4.0“端口”(我没有源代码)WeakEventManager-Class因为我需要它而且我们无法更新到.Net 4.0。我所做的一切都是正确的,但我无法删除任何事件处理程序。
答案 0 :(得分:1)
当您说eventReceiver.OnStateChanged
并将该表达式转换为EventHandler<EventArgs>
时,您每次都会创建一个新的委托实例。方法本身没有单个关联委托。您可以将任意多个委托绑定到同一方法。
ConditionalWeakTable
类似乎对其键使用引用相等。遗憾的是,由于基础ConditionalWeakTable
工具不公开,因此无法构建具有不同语义的自定义internal struct DependentHandle
。
解决方案:始终传递相同的委托实例。