c# - 枚举相等(和 EventHandlerList 的键)

标签 c# events

副标题:EventHandlerList 键的类型可以是对象以外的类型吗?

我想使用枚举存储我想要在事件处理程序中拥有的键。

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 的代码后,我发现问题来自 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;
}

两个比较的 key 都来 self 的 Enum ,但它们并不相等! 我猜它来自对 object 的一些隐式转换正在发生(列表中存储的键的类型为 object ),但我对如此低级的概念不够流畅。

我的猜测对吗?

使用 Enum 的最佳方式是什么?作为 EventHandlerList 中的键?

现在我将创建自己的 EventHandlerListEnum作为键类型。

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

最佳答案

试试这个代码。你能解释一下输出吗?

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);

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

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

EventHandlerList 是密封类,因此您不能影响其内部,但在您自己的代码中,您可以通过更好的检查来处理这种情况:

next.key.Equals(key)

关于c# - 枚举相等(和 EventHandlerList 的键),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12301676/

相关文章:

c# - 在 Visual Studio 2015 中使用 ADO.NET 和 MySQL

c# - 如何让我的 C# PictureBox 传播鼠标事件? (提供截图)

javascript - A-tag 中的 Fire Click 事件

c# - 延迟触发 Lightswitch 自动完成过滤器

events - F# 使用代理将历史事件与两个代理之间的模拟交互交错

events - 内核请求监听器中具有 403 http 状态的 Symfony 异常

没有继承的 C++ 函数指针(回调)

c# - FileLoadException : Moq and Moq. 资源

c# - WP7 中的 Protobuf-net 抛出 FieldAccessExceptions

c# - 你如何为单元测试最小化一个类