【发布时间】:2020-09-10 16:42:13
【问题描述】:
我有一个接收泛型类型的接口,我们称它为 IFoo。该泛型类型被限制为由不同的接口 IBar 实现。这两个接口定义如下:
internal interface IFoo<out TBar> where TBar : IBar
{
}
internal interface IBar
{
}
然后我创建了两个类,每个类都实现了上面创建的接口:
internal class SpecificFoo : IFoo<SpecificBar>
{
}
internal class SpecificBar : IBar
{
}
一切正常,实例化 SpecificFoo 不会产生任何编译错误,因为在定义泛型类型 IBar 时使用了协变。
// No compile error and instantiation works!
IFoo<IBar> correctFoo = new SpecificFoo();
由于我总是使用接口 IFoo 和接口 IBar 来存储派生类的新实例,因此我的代码中到处都是 IFoo 类型的变量。为了简化这个定义,我为 IFoo 接口创建了第二个变体:
internal interface IFoo : IFoo<IBar>
{
}
问题是现在新对象的实例化不像以前那样工作了。
// Compile error!!
IFoo incorrectFoo = new SpecificFoo();
// Cast error!!
IFoo alsoIncorrectFoo = (IFoo)new SpecificFoo();
为什么编译器不够“聪明”,无法理解 IFoo 或具有泛型 IBar 的 IFoo 是同一件事?为什么演员表不起作用?
【问题讨论】:
-
IFoo和IFoo<IBar>不是一回事。IFoo是IFoo<IBar>的子类型,所以IFoo是IFoo<IBar>,但IFoo<IBar>不一定是IFoo。 -
@Luke Woodward 虽然 IFoo
与 IFoo 没有直接关系,就像反过来一样,因为我限制 TBar 来实现 IBar,我认为它们应该是同一件事
标签: c# inheritance interface casting covariance