繁体   English   中英

使用通用接口进行C#转换

[英]C# casting with generic interfaces

我试图理解为什么在这种情况下铸造不起作用。

假设以下接口:

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

这要求您的界面是协变的

public interface IHandler<out T> : where T : IDomainEvent

但是,您的界面本身不支持这一点,因为它有效地逆转。 允许此工作不是类型安全的,并且没有直接的解决方法。 协变接口只允许返回T ,不接受T作为方法的参数。

有关详细信息,请参阅通用接口中的差异

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM