私は単語の正確な意味を理解しようとしており、Covariance
オンラインContravariance
のいくつかの記事と StackOverflow に関する質問から、理解できることから、それはポリモーフィズムの別の単語にすぎません。
上記のステートメントで正しいですか?それとも間違っていますか?
私は単語の正確な意味を理解しようとしており、Covariance
オンラインContravariance
のいくつかの記事と StackOverflow に関する質問から、理解できることから、それはポリモーフィズムの別の単語にすぎません。
上記のステートメントで正しいですか?それとも間違っていますか?
それは確かにポリモーフィズムに関連しています。しかし、それらがポリモーフィズムの単なる「別の言葉」であるとは言えません。これらは非常に特殊な状況に関するものであり、特定のコンテキストで1つのタイプを別のタイプであるかのように扱うことができます。
たとえば、通常のポリモーフィズムでは、Banana
aへの参照を-への参照として扱うことができますが、タイプが表示されるたびにFruit
置換できるわけではありません。たとえば、aはに対して有効ですが、に対しては有効ではないため、として扱うことはできません。Fruit
Banana
List<Banana>
List<Fruit>
list.Add(new Apple())
List<Fruit>
List<Banana>
共分散により、APIで「より大きな」(具体性の低い)型を置き換えることができます。この場合、元の型は「出力」位置でのみ使用されます(たとえば、戻り値として)。共変性により、元のタイプが「入力」位置でのみ使用されるAPIで、「より小さな」(より具体的な)タイプを置き換えることができます。
1つのSO投稿ですべての詳細を説明するのは難しいです(ただし、他の誰かがこれよりも優れた仕事をすることを願っています!)。Eric Lippertには、それに関する一連の優れたブログ投稿があります。
みんな、叫び声をありがとう。
Jon と Rasmus の回答は問題ありません。簡単なテクニカル ノートを追加します。
さりげなく、くだけた言い方をするときは、「共分散」と「反分散」を使って特定の種類のポリモーフィズムを指します。つまり、一連のクモを一連の動物であるかのように扱う一種のポリモーフィズムです。
すべてのコンピューター科学を取得して、より技術的な定義を作成しようとした場合、共分散と反分散が「一種のポリモーフィズム」であるとはおそらく言わないでしょう。次のようなより技術的な定義にアプローチします。
まず、C# には 2 種類のポリモーフィズムがあり、それらを混同しないことが重要です。
最初の種類は、伝統的に「アドホック ポリモーフィズム」と呼ばれます。これは、メソッド M(Animal x) があり、クモ、キリン、ワラビーをそれに渡すポリモーフィズムであり、メソッドは渡された引数を同じように一様に扱います。 Animal 基底クラスによって保証された共通性を使用する方法。
2 番目の種類は、伝統的に「パラメトリック ポリモーフィズム」または「ジェネリック ポリモーフィズム」と呼ばれています。これは、ジェネリック メソッドを作成M<T>(T t)
し、T の制約によって保証された共通性に基づいて引数を一様に処理するメソッドに一連のコードを含める機能です。
あなたは最初の種類のポリモーフィズムについて話していると思います。しかし、私が言いたいのは、ポリモーフィズムを、既知の共通性に基づいて異なるものを一様に扱うプログラミング言語の能力として定義できるということです。(たとえば、既知の基本型、または既知の実装されたインターフェイス)。
共変性と反変性は、型引数の既知の共通点から推定されるジェネリック型間の共通点を利用するプログラミング言語の機能です。
共変性と反変性は、ポリモーフィズムの高度な形式であると考えることができます。共変性と反変性を伴う親クラスであるかのように子クラスを使用できるだけでなく、ポリモーフィズムは多態性クラスに関連するクラスにまで拡張されます。
2つのクラスを想像してみてください。
public class Pet { /*...*/ }
public class Cat:Pet { /*...*/ }
ポリモーフィズムは、Cat
として使用することができますPet
:
void Feed(Pet pet) { /* ... */ }
Cat cat = ...
Feed(cat);
共変性と反変性は、を(共分散)ICollection<Cat>
として使用できることについて話すために使用されます。ICollection<Pet>
void FeedAll(ICollection<Pet> pets) { /* ... */ }
List<Cat> cats = ...
FeedAll(cats);
または(共変性)Action<Pet>
としてを使用するには:Action<Cat>
Action<Pet> GetFeeder() { /* ... */ }
Action<Cat> feeder = GetFeeder();
Eric Lippertは、最初に機能を設計したときに、それについてすばらしいブログシリーズを書きました。パート1はここにあります。
このコレクションを見つけました:
C# における共分散と反分散、パート 3: メンバー グループの変換分散
C# における共分散と反分散、パート 4: 実際のデリゲート分散
C# における共分散と反分散、パート 5: 高次関数は私の脳を傷つけます
C# の共分散と反分散、パート 6: インターフェイスの分散
それは特別な種類のポリモーフィズムであり、別の言葉ではないと思います。これは、ベースの戻り型を持つデリゲートが子型を受け入れることができるデリゲートのポリモーフィズムです。