为什么通用参数不能投射?

AlG*_*AlG 7 c# .net-core

我遗漏了一些基本的东西,但我无法理解.鉴于:

abstract class EventBase {}
class SpecialEvent : EventBase {}
Run Code Online (Sandbox Code Playgroud)

在另一个课程中,我希望允许呼叫者能够 RegisterFor<SpecialEvent>(x => {...})

public class FooHandler {
{
    internal Dictionary<Type, Action<EventBase>> _validTypes = new Dictionary<Type, Action<EventBase>>();

    internal void RegisterFor<T>(Action<T> handlerFcn) where T: EventBase
    {
        _validTypes.Add(typeof(T), handlerFcn);
    }
 }
Run Code Online (Sandbox Code Playgroud)

但是,该_validTypes.Add行无法编译.它无法将a转换Action<T>Action<EventBase>.约束指定T必须从中派生出来EventBase,所以我误解了什么?

das*_*ght 6

C#是不正确的.要了解原因,请考虑以下情况:

// This is your delegate implementation
void SpecialAction(SpecialEvent e) {
    Console.WriteLine("I'm so special!");
}

// This is another EventBase class
class NotSoSpecialEvent : EventBase {}

void PureEvil(Action<EventBase> handlerFcn) where T: EventBase {
    handlerFcn(new NotSoSpecialEvent()); // Why not?
}
Run Code Online (Sandbox Code Playgroud)

让我们想象一下,C#允许你通过Action<SpecialEvent>Action<EventBase>.接下来会发生什么:

PureEvil(SpecialAction); // Not allowed
Run Code Online (Sandbox Code Playgroud)

现在PureEvil将尝试通过NotSoSpecialEvent委托SpecialAction这需要SpecialEvent,它必须永远不会发生.