21


3

以下のコードがC#で正当でない理由は何かありますか。

クラスX:IA、IB {public X test()//準拠エラー、XはIBではないと言う{return this;} }}

インタフェースIA {IB test(); }インターフェイスIB {};

6 Answer


30


この機能は「戻り型共分散」と呼ばれます。 C#は次の理由でそれをサポートしていません。

1)CLRはそれをサポートしていません。 C#で機能させるためには、戻り型を正しいものに変換するための小さなヘルパーメソッドをたくさん用意する必要があります。 あなたがそれを自分でやるのを妨げるものは何もありません。

2)Andersは、戻り型共分散は良い言語機能ではないと考えています。

3)\私たちはその言語に対してもっと高い優先順位を持っています。 予算は限られているため、どのリリースでも可能な限り最高の機能を実行するようにしています。 確かに、これはいいでしょうが、あなたがしたいのならそれはあなた自身でするのに十分に簡単です。 開発者エクスペリエンスを向上させる機能を追加したり、表現力を言語に追加する機能を追加するのに時間をかけたほうがよいでしょう。


16


問題を回避するために明示的なインターフェース実装を使用することができます。

クラスX:IA、IB {public X test(){これを返す。 }

IB IA.test(){これを返す。 }}

インタフェースIA {IB test(); }

インタフェースIB {}


5


シグニチャはインターフェイスが規定するものに丁度一致する必要があります。 メソッドから X`のインスタンスを返すことができない理由はありませんが、メソッドシグネチャは IB`を使用する必要があります。

合理的な理由としては コードの読みやすさの観点からは、おそらくそれが望ましいでしょう。

インターフェースを明示的に実装して、インターフェースによって定義されていない X`を返す代替の署名を提供することができます。 あなたの `IA`が実際に X`であることを知っていれば、代わりにそれを使うことができます。


3


なぜならC#はコンパイル時にインターフェースの同一性と矛盾をサポートしないからです。 このように、IA.Test()メソッドの実装はその宣言と正確に一致しなければなりません。 ただし、実行時にXのインスタンスを返すことはできます


1


パブリックXテスト();

抽象クラスではないクラスのすべてのメソッドに対して本体を宣言する必要があります。

これを試して:

クラスX:IA、IB {public IB test(){return new X(); }}

インタフェースIA {IB test(); }インターフェイスIB {};


1


これはhttp://geekswithblogs.net/abhijeetp/archive/2010/01/10/covariance-and-contravariance-in-c-4.0.aspxに役立ちます。 "out"キーワードを使用できます。