我想弄明白为什么在这种情况下选角不起作用。
假设以下接口:

public interface IDomainEvent { }

public interface IHandler<T> where T: IDomainEvent
{
    void Handle(T args);
}

这些简单的实现:
public class SomeEvent : IDomainEvent
{
    public string Value { get; set; }
}

public class SomeEventHandler : IHandler<SomeEvent>
{
    public void Handle(SomeEvent args) { }
}

我不明白为什么我不能演这个角色:
var handler = new SomeEventHandler() as IHandler<IDomainEvent>;

我使用autofac来解析基于事件的处理程序列表,它做得很好,但是它创建了完全具体的处理程序,在运行时我需要通过接口处理它们。我可以很容易地使用反射来调用handle方法,但看起来这应该是可行的:/

最佳答案

在概念上不能把IHandler<SomeEvent>当作IHandler<IDomainEvent>来对待。IHandler<IDomainEvent>需要能够接受AThirdEvent的实例(实现IDomainEvent)作为Handle的参数,但是您的SomeEventHandler类型不能接受AThirdEvent实例,只能接受SomeEvent实例。
编译器正确地通知您,从概念的角度来看,此类型转换无效。
从概念上讲,你的界面实际上是相反的。如果您有一个IHandler<IDomainEvent>可以隐式地将其转换为IHandler<SomeEvent>(如果您调整了接口的定义以通知编译器它实际上是逆变的),因为如果您的Handle方法可以接受任何类型的IDomainEvent,那么很明显它可以接受每一个SomeEvent

07-25 20:33