これは .Net Framework の変性(共変性と反変性)に関する記事です。
記事中にサンプルコードを示す必要がある場合 C# を使います。
元々は数学で使われていた言葉が、20世紀の終わりにコンピューター科学の分野でも使われるようになり、更にそれが C# のバージョン 4.0 になって使われるようになったそうです(Wikipediaソース)。
数学、コンピューター科学、C# と、3つの分野で使われている言葉ですが、なんとなくニュアンスは同じ気はするものの、使い方は違います。
なので、共変性と反変性の話をするときは、どの分野の話なのか?を明確にしてから話す必要がありそうです。
C# の開発元マイクロソフト公式に、C# の変性について説明しているドキュメントがあるのですが、初めて読んだときは全く意味が分かりませんでした。
そのドキュメントはこちら
何度か読み直してようやく意味がつかめたので、かみ砕いて説明します。
なんとなくイメージをつかむために、まずは大雑把な説明をします。
C# の共変性と反変性は、
親クラスの入れ物に子クラスを入れられるか?
それとも、
子クラスの入れ物に親クラスを入れられるか?
を示す言葉です。
前者が可能な場合、共変性があると言います。
後者が可能な場合、反変性があると言います。
この例では、List<T> が入れ物になります。
using System.Collections.Generic; class Parent {} class Child : Parent {} class test { static void Main() { List<Child> c = new List<Child>(); //子クラスのList<T>を生成 List<Parent> p = c; //親クラスのList<T>に子クラスのList<T>を入れちゃう } }
こういうジェネリックな入れ物(コレクションやインターフェースやデリゲートなど)を使うとき、どの型の入れ物にするか?を宣言しますが、宣言したのとは違う型の入れ物に入れることができます。
ただし、何でもかんでも入ってしまうわけではなく、入れ方にはルールがあります。
冒頭では共変性と反変性のみを紹介しましたが、実際は4種類あります。
1.共変性
2.反変性
3.不変性
4.双変性
以下で、それぞれについて説明します。
子を親に入れられる場合、共変性がある/共変性を持つ/共変性の~/共変の~…みたいな言い方ができます。
親を子に入れられる場合、反変性がある/反変性を持つ/反変性の~/反変の~…みたいな言い方ができます。
どっちもできない場合、不変性がある/不変性を持つ/不変性の~/不変の~…みたいな言い方ができます。
どっちもできる場合、双変性がある/双変性を持つ/双変性の~/双変の~…みたいな言い方ができます。
※公式のドキュメントには、双変性や双変という言葉は出てきません。
※代わりに「変性」という言葉が出てきます。
共変性と反変性の両方を指す場合は、変性と言う事ができます。
※双変性と同じ?