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ます
  • インターフェイスを明示的に実装し、メソッドGetBarから呼び出すだけですIFoo.GetBar()

私が本当に求めているのは、上記のコードをコンパイルするだけではない理由です。上記がで指定された契約を履行しない場合はありますかIFoo

4

3 に答える 3

21

通常、このような機能をサポートすることの複雑さの増加に対して、メリットのバランスをとる場合だと思います。(すべての機能は設計、文書化、実装、テストに労力を要し、開発者もそれらについて教育を受ける必要があります。)たとえば、インターフェイスを実装した値型の戻りをサポートしたい場合は、かなり複雑になる可能性があることに注意してください。 (それは単なる参照ではなく、異なる表現になってしまうため)。

この場合、CLRがそのような機能をサポートしているとは思わないため、C#でこれをクリーンに行うことは非常に困難です。

私はそれが有用な機能であることに同意しますが、必要な追加の作業を正当化するのに十分に有用であるとは見なされていないと思います。

于 2012-05-29T09:47:31.127 に答える
7

あなたが求めている機能は「リターン型共分散」と呼ばれます。ウィキペディアに記載されているように、JavaとC ++の両方にそれがあります。これは、C#にないことをおそらく驚くべきことです。

Eric Lippertは、この回答のコメントで、この機能は実装作業の価値がないと見なされたため、実装されなかったことを確認しています。(この回答の以前の改訂では、その決定に対する責任がエリックに個人的に割り当てられました。彼は、これは正しくなく、誰かが責任を負っている場合はアンダース・ヘルスバーグであると述べています。)

とにかく、言語に追加するためのさまざまな提案があります(https://github.com/dotnet/roslyn/issues/357、https://github.com/dotnet/csharplang/blob/master/proposals/covariant参照) -returns.mdhttps://github.com/kingces95/coreclr/issues/2)、おそらく今後数年で実装されるでしょう。これらの議論によると、この機能が原則としてC#に存在してはならないという重大な理由があるようには思えません。むしろ、これまでのところ、実装する価値があると判断されることはありません。

于 2017-09-11T23:49:21.323 に答える
1

機能が努力を正当化するように感じなかったので、それは実装されませんでした。しかし、良いニュースがあります。

この機能は、2020年3月にMads Torgersenによって、今後のC#9.0の投稿で発表されました。

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