c# - 为什么在通用上下文中不能将继承的接口转换为其基本接口?
问题描述
我试图在我的 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>”
为什么转换是不可能的?
解决方案
您无法进行分配,因为基类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();
}
推荐阅读
- hellosign-api - HelloSign 模板 - 不显示我(发送时)
- amazon-web-services - 如何在从 ALB 目标组中删除的 EC2 实例上执行脚本?
- scala - 如何从scala案例类中的伴随应用方法调用构造函数?
- blazor - 如何在 Blazor 代码后面将方法传递给 EventCallback?
- bash - Bash : Remove all directories except one
- python - 使用 python 正则表达式替换 HTML Snippet 中的块
- python - 带有 CV2 库的 Python 机器人脚本
- react-native - React Native 重新加载应用或刷新 Drawer.Navigator
- excel - 将表格从word文件导入excel文件
- sql - 从 SQL 数据库中选择除重复项之外的所有内容