首页 > 解决方案 > 为什么在通用上下文中不能将继承的接口转换为其基本接口?

问题描述

我试图在我的 C# 项目中实现一个接口继承系统,但我无法让它工作。

这是一个简化版本:

public interface BaseInterface {}

public abstract class AbstractClass<T> where T : BaseInterface {}

public interface ChildInterface : BaseInterface {}

public class ConcreteClass : AbstractClass<ChildInterface> {}

我想按如下方式使用它:

AbstractClass<BaseInterface> c = new ConcreteClass();

最后一行代码给了我以下错误:

无法将类型“ConcreteClass”隐式转换为“AbstractClass<BaseInterface>”

为什么转换是不可能的?

标签: c#

解决方案


您无法进行分配,因为基类AbstractClass<T>, 是不变的。您希望能够进行这种分配的是协变类型。定义协变和逆变仅限于接口,这意味着我们需要另一个接口。

public interface IAbstractClass<out T> where T : BaseInterface { }  
public abstract class AbstractClass<T> : IAbstractClass<T> where T : BaseInterface { }

关键字将out泛型类型参数标记为协变。然后我们在 中实现该接口AbstractClass<T>,我们的其他类型可以通过该接口按预期工作。这些也是我们需要进行的唯一更改,我们将其他类型定义保持不变:

public interface BaseInterface { }
public interface ChildInterface : BaseInterface { }

public class ConcreteClass : AbstractClass<ChildInterface> { }

我们现在有一个AbstractClass<T>实现的协变接口,你可以做你想要的那种分配,但你必须以IAbstractClass接口为目标。

public void Main() {
    IAbstractClass<BaseInterface> c = new ConcreteClass();
}

推荐阅读