使用EventHandler作为键的ConditionalWeakTable

时间:2014-02-11 08:54:00

标签: c#

我尝试将一个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。我所做的一切都是正确的,但我无法删除任何事件处理程序。

1 个答案:

答案 0 :(得分:1)

当您说eventReceiver.OnStateChanged并将该表达式转换为EventHandler<EventArgs>时,您每次都会创建一个新的委托实例。方法本身没有单个关联委托。您可以将任意多个委托绑定到同一方法。

ConditionalWeakTable类似乎对其键使用引用相等。遗憾的是,由于基础ConditionalWeakTable工具不公开,因此无法构建具有不同语义的自定义internal struct DependentHandle

解决方案:始终传递相同的委托实例。