为什么在通用上下文中不能将继承的接口转换为其基本接口? [英] Why an inherited interface can't be converted to its base interface in generic context?
问题描述
我正在尝试在我的C#项目中实现接口继承系统,但是我无法使其正常工作。
I'm trying to implement an interface inheritance system in my C# project, but I can't get it to work.
这是一个简化的版本:
public interface BaseInterface {}
public abstract class AbstractClass<T> where T : BaseInterface {}
public interface ChildInterface : BaseInterface {}
public class ConcreteClass : AbstractClass<ChildInterface> {}
我想按以下方式使用它:
I want to use it as follow:
AbstractClass<BaseInterface> c = new ConcreteClass();
最后一行代码给我以下错误:
The last line of code gives me the following error:
不能将类型'ConcreteClass'隐式转换为'AbstractClass< BaseInterface>'
Cannot implicitly convert type 'ConcreteClass' to 'AbstractClass<BaseInterface>'
为什么
推荐答案
您无法进行分配,因为基类 AbstractClass< T>
是不变的。您希望能够进行这种分配的是协变类型。定义协方差和相反方差仅限于接口,因此这意味着我们需要另一个接口。
You aren't able to make the assignment because the base class, AbstractClass<T>
, is invariant. What you want to be able to make that kind of assignment is a covariant type. Defining Covariance and Contravariance is limited to interfaces, so that means we need another interface.
public interface IAbstractClass<out T> where T : BaseInterface { }
public abstract class AbstractClass<T> : IAbstractClass<T> where T : BaseInterface { }
输出
关键字将通用类型参数标记为协变。然后,我们在 AbstractClass< T>
中实现该接口,并且其他类型可以通过该接口正常工作。这些也是我们唯一需要做的更改,其他类型定义保持不变:
The out
keyword marks the generic type parameter as covariant. We then implement that interface in AbstractClass<T>
, and our other types can work expected through the interface. These are also the only alterations we need to make, we leave the other type definitions the same:
public interface BaseInterface { }
public interface ChildInterface : BaseInterface { }
public class ConcreteClass : AbstractClass<ChildInterface> { }
我们现在有了 AbstractClass< T>
实现,您可以执行所需的分配,但是必须定位 IAbstractClass
接口。
We now have a covariant interface that AbstractClass<T>
implements, and you can do the kind of assignment you desire, but you'll have to target the IAbstractClass
interface.
public void Main() {
IAbstractClass<BaseInterface> c = new ConcreteClass();
}
这篇关于为什么在通用上下文中不能将继承的接口转换为其基本接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!