【问题标题】:EventHandlerList with Guid always null带有 Guid 的 EventHandlerList 始终为空
【发布时间】:2022-01-12 12:54:21
【问题描述】:

我正在尝试实现 HTTP 服务器发送的事件,如 this Stack Overflow 答案中所示。答案会在事件中向所有订阅者发出通知。我希望只有特定的客户接收事件通知(因此只有执行某些操作来触发事件的客户才会收到通知,而不是所有人)。

我正在使用 EventHandlerList 注册处理程序,使用 Guid 作为键。相关sn-p代码:

public class MessageRepository
{
    private readonly EventHandlerList _eventHandlerList;

    public MessageRepository()
    {
        _eventHandlerList = new EventHandlerList();
    }

    public void Subscribe(Guid guid, Delegate handler)
    {
        _eventHandlerList.AddHandler(guid, handler);
    }

    public void Unsubscribe(Guid guid, Delegate handler)
    {
        _eventHandlerList.RemoveHandler(guid, handler);
    }

    public void Notify(Guid guid, string message)
    {
        _eventHandlerList[guid]?.DynamicInvoke(this, new Message(message));
    }
}

不幸的是,_eventHandlerList[guid] 总是返回为 null。我已经验证了使用 Dictionary<Guid, Delegate> 代替 EventHandlerList 的类似实现可以正常工作。为什么?

【问题讨论】:

  • Guid 是一个结构。不幸的是,EventHandlerList 将键与 == 运算符进行比较。
  • @shingo guid 是相同的(当前设置为 Guid.Empty 用于测试),所以我认为这不是问题所在。 == 运算符进行值检查并按预期返回 true。
  • 如果比较两个对象的引用,请检查我的答案。
  • “操作员进行值检查并返回 true,正如预期的那样” - 不,它 does not

标签: c#


【解决方案1】:

Guid 是一个结构体,不幸的是 EventHandlerList compares keys with == operator.

var guid = Guid.NewGuid();
object key1 = guid;
object key2 = guid;
Console.WriteLine(key1 == key2); // False

The document 建议使用空对象作为键。如果要使用 guid,则必须保留并使用它的相同引用。

object guid = Guid.NewGuid();
_eventHandlerList.AddHandler(guid, handler);
Console.WriteLine(_eventHandlerList[guid]);

字典(和 .net 中的其他集合)使用 Equals 来比较键,这就是它适用于 guid 的原因。

【讨论】:

  • 你是对的。昨晚大脑争先恐后地跑了Equals和==。我认为在这种情况下坚持使用字典可能更容易。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
相关资源
最近更新 更多