34

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

我们举个例子来说明:

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, 或
  • 显式实现接口并GetBarIFoo.GetBar()方法中调用

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

4

3 回答 3

21

通常,我会说这将是平衡好处与支持此类功能所增加的复杂性的情况。(所有功能都需要努力设计、记录、实现、测试,然后开发人员也需要接受有关它们的教育。)请注意,如果您想支持返回实现接口的值类型,可能会有一些显着的复杂性,例如(因为这最终会以不同的表示形式出现,而不仅仅是参考)。

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

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

于 2012-05-29T09:47:31.127 回答
7

您要询问的功能称为“返回类型协方差”。正如Wikipedia 上所指出的,Java 和 C++ 都有它,这也许让 C# 没有它令人惊讶。

Eric Lippert 在对此答案的评论中确认,此功能未实施,因为它被认为不值得实施工作。(此答案的先前修订版将这一决定的责任分配给了埃里克个人;他说这是不正确的,如果有人对此负责,那就是安德斯·海尔斯伯格。)

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

于 2017-09-11T23:49:21.323 回答
1

它没有被实现,因为他们觉得这个功能不能证明付出的努力。但也有好消息。

此功能已由Mads Torgersen 在 2020 年 3 月的一篇文章中宣布,用于即将推出的 C# 9.0

abstract class Animal
{
    public abstract Food GetFood();
    ...
}
class Tiger : Animal
{
    public override Meat GetFood() => ...;
}
于 2020-08-17T11:28:25.147 回答