When you have a MyCallback<Event>
you're saying that you have a method that can take any type of event. It can accept an EventOne
, or an EventTwo
, or a SomeOtherEvent
.
Let's say I call RegisterCallback
and pass in a delegate pointing to a method with this signature:
public static void Foo(SomeOtherEvent arg)
If your code would work, and I could assign that to a MyCallback<Event>
, then I could pass in an EventOne
instance to that method when calling it. That's obviously a problem.
There's a term for that; you're expecting MyCallback
to be covariant with respect to it's generic argument. In fact, it's contravariant. If I have a method that can accept any type of event, I can clearly pass in a SomeEvent
, or a SomeOtherEvent
, meaning I could assign a MyCallback<Event>
to a MyCallback<SomeOtherEvent>
, rather than the other way around.
If you want to tell the compiler that, "I know that this method cannot actually be called with any type of event, but I want you to allow this check and only fail at runtime if the given argument is not of the proper type." then you can do that, assuming you actually have a way of ensuring you call each callback with the proper arguments. You can't just do a cast either; you need to wrap the method in a new method that does the cast:
eventTable.Add("test", e => callback((T)e));