Reputation: 739
I wanted to use an enum store the keys I would like to have in an 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 it turns out it does not work. But it works if I use keys declared like (as shown on):
static object EventKeyOnTap = new object();
After reading some mscorlib's code I see that the problem comes from next.key == key
in
private EventHandlerList.ListEntry Find(object key)
{
EventHandlerList.ListEntry next = this.head;
while (next != null && next.key != key)
{
next = next.next;
}
return next;
}
Both compared keys are from my Enum
, but they are not equal!
I guess it comes from some implicit casts to object
happening (the key stored in the list is of type object
) but am not fluent enough with such low-level concepts.
Is my guess right?
Enum
as a key in an EventHandlerList
?For now I will create my own EventHandlerList
with Enum
as key Type.
For now I created my own EventHandlerList
with a constructor taking a Func<object, object, bool>
which I then use in place of the equality comparaison aforementioned.
Upvotes: 2
Views: 640
Reputation: 3407
Try this code. Can you explain output?
var bark1 = (object)EventKey.OnBark;
var bark2 = (object)EventKey.OnBark;
Console.WriteLine(bark1 != bark2);
Console.WriteLine(bark1.Equals(bark2));
If yes, I don't know why you asked this question. If no, you definitely should get aware of value types, reference types and boxing.
In short, AddHandler
method accepts object
parameter, hence your key (which is value type) is boxed when you call:
EventList.AddHandler(EventKey.OnBark, value);
If you call this method twice with the same enum key, key will be boxed twice, and two different objects in heap will be actually created.
That's why this check next.key != key
inside Find
method fails (it compares addresses of two separate objects in heap).
EventHandlerList is sealed class, so you cannot affect its guts, but in your own code you could handle this situation with better check:
next.key.Equals(key)
Upvotes: 3