为什么C#在实现接口时不允许继承返回类型

时间:2009-08-23 21:49:25

标签: c# .net

下面的代码在C#中是否合法,是否有任何合理的理由?

class X: IA, IB
{
    public X test() // Compliation Error, saying that X is not IB
    {
        return this;
    }
}

interface IA 
{
    IB test();
}
interface IB { };

6 个答案:

答案 0 :(得分:31)

此功能称为“返回类型协方差”。由于以下原因,C#不支持它:

1)CLR不支持它。为了使它在C#中工作,我们必须吐出一大堆小助手方法,这些方法将返回类型转换为正确的东西。没有什么能阻止你自己这样做。

2)Anders认为返回类型协方差不是一个好的语言特征。

3)\我们有很多更高的语言优先级。我们的预算有限,因此我们尝试在任何给定的版本中尽我们所能。当然,这会很好,但如果你愿意的话,这很容易就可以自己做。更好的是,我们花时间添加可以改善开发人员体验的功能,或者为语言添加更具代表性的功能。

答案 1 :(得分:16)

您可以使用显式接口实现来避免此问题。

class  X : IA, IB
{
  public X test()
  {
    return this;
  }

  IB IA.test()
  {
    return this;
  }
}

interface IA
{
  IB test();
}

interface IB
{
}

答案 2 :(得分:5)

签名必须与接口指定的内容完全匹配。您无法从方法中返回X的实例,但方法签名必须使用IB

至于理性的原因......从代码可读性的角度来看,它可能更可取。

您可以显式实现接口,并提供另一个签名,该签名返回未由接口定义的X。如果您知道IA实际上是X,则可以使用它。

答案 3 :(得分:3)

因为C#在编译时不支持接口的协同和逆转。这样,IA.Test()方法的实现必须与其声明完全匹配。但是,您可以在运行时返回X的实例

答案 4 :(得分:1)

public X test();

您必须为任何不抽象的类声明所有方法的主体。

试试这个:

class X : IA, IB
{
    public IB test()
    {
        return new X();
    }
}

interface IA
{
    IB test();
}
interface IB { };

答案 5 :(得分:1)