为什么接口实现不能返回更具体的类型?

时间:2012-05-29 09:44:41

标签: c# interface language-design overloading

如果接口指定了返回另一个接口的属性或方法,为什么第一个接口的实现不允许将返回类型“更改”为更具体的类型?

我们举一个例子来说明:

interface IFoo
{
    IBar GetBar();
}
interface IBar
{ }

class Foo : IFoo
{
    // This is illegal, we are not implementing IFoo properly
    public Bar GetBar()
    {
        return new Bar();
    }
}

class Bar : IBar
{ }

我知道如何让它发挥作用,我的担忧。

我可以:

  • GetFoo()的返回类型更改为IBar
  • 明确实施界面,只需从GetBar方法
  • 调用IFoo.GetBar()即可

我真正要问的是不仅允许上面的代码编译的原因。是否存在上述情况不符合IFoo指定的合同的情况。

3 个答案:

答案 0 :(得分:18)

通常,我会说这是一个平衡利益与支持这种功能的额外复杂性的案例。 (所有功能都需要设计,记录,实现,测试,然后开发人员也需要了解它们。)请注意,如果您想支持返回实现接口的值类型,可能会有一些重大的复杂性,例如(因为它以不同的表示形式结束,而不仅仅是参考)。

在这种情况下,我不相信 CLR甚至支持这样的功能,这将使C#很难干净地完成。

我同意这是一个有用的功能,但我怀疑它并不足以保证所需的额外工作。

答案 1 :(得分:5)

您要问的功能称为"返回类型协方差" 。如前所述on Wikipedia,Java和C ++都有它,这可能会让C#没有意外。

Eric Lippert在对此答案的评论中证实,此功能尚未实施,因为它并不值得付诸实施。 (此答案的先前修订版对Eric的个人负责;他说这是不正确的,如果任何一个人负责,那就是Anders Hejlsberg。)

无论如何,现在有各种建议将其添加到语言中(请参阅https://github.com/dotnet/roslyn/issues/357https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.mdhttps://github.com/kingces95/coreclr/issues/2),因此可能会在未来几年内实施。根据这些讨论,听起来没有任何深刻的理由说明为什么这个特征原则上不应该存在于C# - 相反,它从来没有到目前为止判断值得任何人努力实施。

答案 2 :(得分:1)

它没有实现,因为他们认为该功能不足以证明这样做是合理的。但是有个好消息。

此功能已在post by Mads Torgersen in March 2020中宣布,适用于即将推出的C#9.0

abstract class Animal
{
    public abstract Food GetFood();
    ...
}
class Tiger : Animal
{
    public override Meat GetFood() => ...;
}