21

その制限の本当の理由は何ですか?しなければならなかったのはただの仕事ですか?概念的に難しいですか?無理ですか?

確かに、フィールドは常に読み書き可能であるため、型パラメーターをフィールドで使用することはできません。でもそれじゃ答えにならないよね?

この質問の理由は、私が C# 4 のバリアンス サポートに関する記事を書いているためであり、それがデリゲートとインターフェイスに制限されている理由を説明する必要があると感じています。立証責任を逆転させるだけです。

更新: Eric が例について尋ねました。

これはどうですか(それが理にかなっているのかどうかはまだわかりません:-))

public class Lookup<out T> where T : Animal {
  public T Find(string name) {
    Animal a = _cache.FindAnimalByName(name);
    return a as T;
  }
}

var findReptiles = new Lookup<Reptile>();
Lookup<Animal> findAnimals = findReptiles;

それを 1 つのクラスに持つ理由は、クラス自体に保持されているキャッシュである可能性があります。また、異なる種類のペットに同じ名前を付けないでください。

ところで、これはC# 5.0 のオプションの型パラメーターにつながります :-)

更新 2: CLR と C# がこれを許可する必要があると主張しているわけではありません。何がそれにつながったのかを理解しようとしているだけです。

4

3 に答える 3

21

まず、Tomas が言うように、CLR ではサポートされていません。

第二に、それはどのように機能しますか?あなたが持っていると仮定します

class C<out T>
{ ... how are you planning on using T in here? ... }

T は、出力位置でのみ使用できます。お気づきのように、フィールドに書き込むことができるため、クラスはタイプ T のフィールドを持つことはできません。クラスは、T を取るメソッドを持つことはできません。それらは論理的な書き込みであるためです。あなたがこの機能を持っていると仮定して、それをどのように活用しますか?

これは、たとえば、タイプ T の読み取り専用フィールドを持つことを合法にすることができれば、不変クラスに役立ちます。そうすれば、不適切に書き込まれる可能性を大幅に削減できます。しかし、タイプセーフな方法で差異を許容する他のシナリオを考え出すのは非常に困難です。

そんなシチュエーションがあれば是非見てみたいです。これは、いつかこれを CLR に実装するためのポイントになります。

更新:参照

C# 4.0 のクラスに一般的な差異がないのはなぜですか?

この質問の詳細については。

于 2010-03-29T21:53:54.100 に答える
8

私の知る限り、この機能は CLR ではサポートされていないため、これを追加するには CLR 側でもかなりの作業が必要になります。インターフェイスとデリゲートの共分散と逆分散は、バージョン 4.0 より前の CLR で実際にサポートされていたため、実装するのは比較的簡単な拡張機能でした。

(ただし、クラスでこの機能をサポートすることは間違いなく便利です!)

于 2010-03-29T21:45:38.340 に答える
1

それらが許可された場合、コンストラクターが 1 つ以上の T または T サプライヤーを受け入れた場合、型 T に関して共変である有用な 100% タイプセーフ (内部型キャストなし) クラスまたは構造を定義できます。コンストラクターが 1 つ以上の T コンシューマーを受け入れる場合、T に関して反変である、有用な 100% タイプ セーフなクラスまたは構造体を定義できます。静的ファクトリメソッドを使用するのではなく「新しい」を使用する機能を超えて、インターフェイスよりもクラスに多くの利点があるかどうかはわかりませんが(おそらく、名前がインターフェイスの名前に似ているクラスから)、できます確かに、不変の構造が共分散をサポートする使用例を参照してください。

于 2011-08-24T18:05:25.240 に答える