共変性と反変性の違いを理解するのに苦労しています。
ベストアンサー1
質問は「共変性と反変性の違いは何ですか?」です。
共変性と反変性は、集合の1つのメンバーを別のメンバーに関連付けるマッピング関数より具体的には、写像は共変または反変である可能性がある。関係そのセットで。
すべての C# 型のセットの次の 2 つのサブセットについて考えてみましょう。まず:
{ Animal,
Tiger,
Fruit,
Banana }.
2 番目は、明らかに関連性のあるセットです。
{ IEnumerable<Animal>,
IEnumerable<Tiger>,
IEnumerable<Fruit>,
IEnumerable<Banana> }
そこにはマッピング最初のセットから2番目のセットへの操作。つまり、最初のセットの各Tについて、対応する2 番目のセットに入力する値は ですIEnumerable<T>
。または、短縮形では、マッピングは ですT → IE<T>
。これは「細い矢印」であることに注意してください。
これまでのところ私と一緒に?
さて、関係. があります割り当て互換性関係最初のセットの型のペア間。 型の値はTiger
型の変数に割り当てることができるため、これらの型は「割り当て互換」であると言われています。 「 型の値は 型の変数に割り当てることができる」を、より短い形式でAnimal
書きましょう。 これは「太い矢印」であることに注意してください。X
Y
X ⇒ Y
最初のサブセットには、すべての割り当て互換性関係が次のように示されています。
Tiger ⇒ Tiger
Tiger ⇒ Animal
Animal ⇒ Animal
Banana ⇒ Banana
Banana ⇒ Fruit
Fruit ⇒ Fruit
特定のインターフェイスの共変代入互換性をサポートする C# 4 では、2 番目のセットの型のペア間に代入互換性関係があります。
IE<Tiger> ⇒ IE<Tiger>
IE<Tiger> ⇒ IE<Animal>
IE<Animal> ⇒ IE<Animal>
IE<Banana> ⇒ IE<Banana>
IE<Banana> ⇒ IE<Fruit>
IE<Fruit> ⇒ IE<Fruit>
マッピングに注目してくださいT → IE<T>
割り当て互換性の存在と方向を維持するつまり、 の場合X ⇒ Y
、 も真となりますIE<X> ⇒ IE<Y>
。
太い矢印の両側に 2 つのものがある場合は、その両側を対応する細い矢印の右側にあるものに置き換えることができます。
特定の関係に関してこの特性を持つマッピングは、「共変マッピング」と呼ばれます。これは理にかなっています。動物のシーケンスが必要な場合、虎のシーケンスを使用できますが、その逆は当てはまりません。虎のシーケンスが必要な場合、動物のシーケンスを必ずしも使用できるとは限りません。
これが共変性です。次に、すべてのタイプの集合のこのサブセットを考えてみましょう。
{ IComparable<Tiger>,
IComparable<Animal>,
IComparable<Fruit>,
IComparable<Banana> }
これで、最初のセットから 3 番目のセットへのマッピングができましたT → IC<T>
。
C# 4 の場合:
IC<Tiger> ⇒ IC<Tiger>
IC<Animal> ⇒ IC<Tiger> Backwards!
IC<Animal> ⇒ IC<Animal>
IC<Banana> ⇒ IC<Banana>
IC<Fruit> ⇒ IC<Banana> Backwards!
IC<Fruit> ⇒ IC<Fruit>
つまり、マッピングT → IC<T>
は存在は維持したが方向は逆転した代入互換性。つまり、 の場合X ⇒ Y
、 となりますIC<X> ⇐ IC<Y>
。
マッピング保存するが逆転する関係は反変マッピング。
これも明らかに正しいはずです。2 匹の動物を比較できるデバイスは 2 匹のトラも比較できますが、2 匹のトラを比較できるデバイスは必ずしも 2 匹の動物を比較できるとは限りません。
これがC#4における共変性と反変性の違いです。共変性保存する割り当ての方向。反変性逆転するそれ。