12

重複の可能性:
C# は戻り型の共分散をサポートしていますか?

ただのバカなのかも知れない…

インターフェイスがある場合:

public interface IMoop
{
    object Moop();
}

なぜそのように実装できないのですか (これは暗黙の共分散を使用すると思いますか?)

public class MoopImplementor : IMoop
{
    string Moop();
}

MoopImplementor のインスタンスは IMoop によって指定された契約を満たすため、これで問題ないようです。

教えてください:)

編集:明確にするために-実装クラスはInterfacedメソッドの戻り値の型から継承するものを返すため、これは機能するはずだと思います。具体的には、stringIS とobject. (そして、他の継承チェーンについても同じことが言えます)。

4

5 に答える 5

13

C# は、インターフェイスの実装または仮想メソッドのオーバーライドを目的とした戻り値の型の共変性をサポートしていません。詳細については、この質問を参照してください。

C# は戻り値の型の共分散をサポートしていますか?

C# は、C# 4 の時点で、型引数の参照型を使用して構築されたインターフェイスとデリゲート型の一般的な共変性と反変性をサポートしています。

また、C# は、参照型を返すメソッドを、戻り値の型が互換性のある参照型であるデリゲート型に変換するときに、戻り値の型の共分散をサポートします。(同様に、パラメーター型の反変性をサポートします。)

このテーマに興味がある場合は、C# でサポートされているバリアンスとサポートされていないバリアンスのさまざまなバージョンについて説明した多数の記事を書いています。見る

https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/

詳細については。

于 2012-04-26T17:21:20.957 に答える
7

インターフェイスは、メソッドが を返さなければならないことを指定しているためobjectです。はstringから継承objectできますが、インターフェイスは、より一般的な型を返すメソッドを指定します。

ただし、次のことを行うことを妨げるものは何もないことに注意してください。

public object Moop()
{
    return "Some new string";
}
于 2012-04-26T17:03:12.120 に答える
4

合理的な回避策:

public class MoopImplementor : IMoop {
  public string Moop() { ... }
  object IMoop.Moop() { return Moop(); }
}

これにより、公開されている実装MoopImplementorは、インターフェイスの要件を満たしながら、より正確な型を持つことができます。

于 2012-04-26T17:07:57.223 に答える
3

あなたは契約を満たしていません。ただし、ジェネリックを使用してこれを行うことができます。

public interface IMoop<T>
{
    T Moop();
}

public class MoopImplementor : IMoop<string>
{
    public string Moop() { return ""; }
}
于 2012-04-26T17:05:51.797 に答える
2

C# 言語仕様から:

13.4.4 インターフェースのマッピング

インターフェイス マッピングの目的で、クラス メンバー A は次の場合にインターフェイス メンバー B と一致します。

  • A と B はメソッドであり、A と B の名前、、および仮パラメーター リストは同一です

継承や変換可能性については何も述べていないことに注意してください! 戻り値の型は同一でなければなりません。

于 2012-04-26T17:19:56.663 に答える