C#:为什么在通用上下文中无法将继承的接口转换为其基接口?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (5)

我正在尝试在我的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'

为什么转换不可能?

提问于
用户回答回答于

您无法进行分配,因为基类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();
}

扫码关注云+社区

领取腾讯云代金券