この質問には質問がないようですので、いくつかの質問を作成してお答えします。
共変変換とは何ですか?
明らかな関係を持ついくつかの型Fruit
and Apple
andがあるとしましょう。などの一種です。Banana
Apple
Fruit
共変変換とは、型引数の変換可能性がジェネリック型の変換可能性を意味するものです。Apple
が に変換可能Fruit
で、Bowl<Apple>
が に変換可能である場合Bowl<Fruit>
、Bowl<T>
は T で共変です。
反変変換とは何ですか?
反変変換は、方向を維持する代わりに逆にする共変変換です。もしが に変換可能なら、は T で反変です。Eater<Fruit>
Eater<Apple>
Eater<T>
インターフェイスまたはデリゲートを型パラメーターで共変または反変としてマークするにはどうすればよいですか?
共変型パラメータはマークされout
、反変型パラメータはマークされin
ます。
これはニーモニックであることを意図しています。通常、共変インターフェイスでは型パラメーターが出力位置に表示され、反変インターフェイスでは型パラメーターが入力位置に表示されます。
String
に変換可能Object
です。IReadOnlyCollection<String>
に変換可能にするにはどうすればよいIReadOnlyCollection<Object>
ですか?
TIReadOnlyCollection<T>
で共変にします。マークしout
ます。
次のコードを検討してください。
delegate void Action<in T>(T t);
interface IFoo<in X>
{
void M(Action<X> action);
}
なぜコンパイラはこれが有効ではないと言うのですか?
有効ではないためです。理由を見てみましょう。
class Foo : IFoo<Fruit>
{
public void M(Action<Fruit> action)
{
action(new Apple()); // An apple is a fruit.
}
}
...
IFoo<Fruit> iff = new Foo();
IFoo<Banana> ifb = iff; // Contravariant!
ifb.M(banana => { banana.Peel(); });
ロジックに従ってください。このプログラムはリンゴを の「これ」として渡しますがBanana.Peel()
、これは明らかに間違っています。
コンパイラはこれが発生する可能性があることを認識しているため、最初にインターフェイスを宣言することを許可しません。
分散についてさらに質問がある場合はどうすればよいですか?
この機能の設計と実装に関する私の記事を読むことから始めてください。下から始めます。それらは逆の時系列順にリストされています。
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
それでも質問がある場合は、質問が実際に何であるかを人々に推測させるのではなく、実際に質問を含む質問をここに投稿する必要があります。