【.Net C#】共変性と反変性ってなに?

これは .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つ

冒頭では共変性と反変性のみを紹介しましたが、実際は4種類あります。

1.共変性
2.反変性
3.不変性
4.双変性

以下で、それぞれについて説明します。

共変性【きょうへんせい】(covariant)

子を親に入れられる場合、共変性がある/共変性を持つ/共変性の~/共変の~…みたいな言い方ができます。

反変性【はんぺんせい】(contravariant)

親を子に入れられる場合、反変性がある/反変性を持つ/反変性の~/反変の~…みたいな言い方ができます。

不変性【ふへんせい】(invariant)

どっちもできない場合、不変性がある/不変性を持つ/不変性の~/不変の~…みたいな言い方ができます。

双変性【そうへんせい】(bivariant)

どっちもできる場合、双変性がある/双変性を持つ/双変性の~/双変の~…みたいな言い方ができます。

※公式のドキュメントには、双変性や双変という言葉は出てきません。
※代わりに「変性」という言葉が出てきます。

変性

共変性と反変性の両方を指す場合は、変性と言う事ができます。

※双変性と同じ?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です