枚举相等(和EventHandlerList的键)

时间:2012-09-06 13:53:11

标签: c# events

字幕:EventHandlerList键的Type是否可以是对象以外的东西?

我想在枚举存储中使用我希望在EventHandler中使用的密钥。

public enum EventKey
{
    OnBark, OnCry
}

public EventHandlerList EventList = new EventHandlerList();

public event ComplaintEventHandler OnBark
{
    add
    {
        EventList.AddHandler(EventKey.OnBark, value);
    }
    remove
    {
        EventList.RemoveHandler(EventKey.OnBark, value);
    }
}

var handler = EventList[eventKey] as ComplaintEventHandler;

>

handler = null

事实证明它不起作用。但是如果我使用声明为(as shown on)的键:

,它就可以工作
static object EventKeyOnTap = new object();

在阅读了一些mscorlib的代码之后,我发现问题来自{/ 1}}

next.key == key

两个比较密钥都来自我的private EventHandlerList.ListEntry Find(object key) { EventHandlerList.ListEntry next = this.head; while (next != null && next.key != key) { next = next.next; } return next; } ,但它们不相等! 我想它来自于Enum发生的一些隐式转换(列表中存储的密钥是​​object类型)但是对于这种低级概念不够流畅。

我猜对了吗?

object中使用Enum作为关键字的最佳方法是什么?

现在,我将创建自己的EventHandlerList,其中EventHandlerList为关键类型。

现在我创建了自己的Enum,其构造函数采用了EventHandlerList,然后我使用它来代替前面提到的相等比较。

1 个答案:

答案 0 :(得分:3)

试试这段代码。你能解释输出吗?

var bark1 = (object)EventKey.OnBark;
var bark2 = (object)EventKey.OnBark;

Console.WriteLine(bark1 != bark2);
Console.WriteLine(bark1.Equals(bark2));

如果是,我不知道你为什么问这个问题。如果不是,您肯定应该了解值类型引用类型装箱

简而言之,AddHandler方法接受object参数,因此当您致电时,您的密钥(值类型)会被加框:

EventList.AddHandler(EventKey.OnBark, value);

如果使用相同的枚举键调用此方法两次,则键将被装箱两次,并且实际上将创建堆中的两个不同对象。

这就是next.key != key方法中的Find检查失败的原因(它比较了堆中两个独立对象的地址)。

EventHandlerList是密封类,所以你不能影响它的内容,但是在你自己的代码中你可以通过更好的检查来处理这种情况:

next.key.Equals(key)