【问题标题】:Compile error when creating instance of object with generic type interface使用泛型类型接口创建对象实例时编译错误
【发布时间】: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 是同一件事?为什么演员表不起作用?

【问题讨论】:

  • IFooIFoo&lt;IBar&gt; 不是一回事。 IFooIFoo&lt;IBar&gt; 的子类型,所以IFooIFoo&lt;IBar&gt;,但IFoo&lt;IBar&gt; 不一定是IFoo
  • @Luke Woodward 虽然 IFoo 与 IFoo 没有直接关系,就像反过来一样,因为我限制 TBar 来实现 IBar,我认为它们应该是同一件事

标签: c# inheritance interface casting covariance


【解决方案1】:

如果我理解这个问题,你需要让SpecificFoo实现IFoo

internal class SpecificFoo : IFoo<SpecificBar>, IFoo
{ .. }

这会让你

IFoo correctFoo = new SpecificFoo();
//and
IFoo<IBar> anotherFoo = correctFoo;

【讨论】:

  • 是的,这行得通!非常感谢!这是有道理的,SpecificFoo 和 IFoo 之间需要有直接关系,因为 IFoo 不一定是 IFoo,就像@Luke Woodward 说的那样
猜你喜欢
  • 2015-05-21
  • 2018-04-03
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
相关资源
最近更新 更多