1. ホーム
  2. c#

[解決済み] 共分散と共分散の違いについて

2022-05-03 09:29:29

質問

共分散と共分散の違いがわからなくて困っています。

どのように解決するのですか?

共分散と共分散の違いは何ですか?

共分散と共分散は、以下の特性です。 ある集合のメンバーを別の集合に関連付ける写像関数 . より具体的には,写像は 関係 をその集合の上に置く。

C#の全型の集合のうち、次の2つの部分集合を考える。まず

{ Animal, 
  Tiger, 
  Fruit, 
  Banana }.

そして2つ目は、この明らかに関連性のあるセットです。

{ IEnumerable<Animal>, 
  IEnumerable<Tiger>, 
  IEnumerable<Fruit>, 
  IEnumerable<Banana> }

があります。 マッピング の操作で、最初のセットから2番目のセットへ移動します。すなわち、第一集合の各Tに対して 対応する の型は、第二集合の 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の共分散と共分散の違いです。 共分散 保存する は、割り当て可能な方向です。反対分散(Contravariance となります。