C#の共反性と反変性

C#における「共反性 (covariance)」とは、代入互換性のある異なる型間での変換を意味します。例えば、IEnumerable<Derived> が IEnumerable<Base> に代入可能である場合、IEnumerable<Derived> はIEnumerable<Base> に共変です。

一方、C#における共反性の反対は「反変性 (contravariance)」です。反変性は、型の継承関係が逆転している場合に、代入互換性があるという意味です。例えば、Action<Base> が Action<Derived> に代入可能である場合、Action<Base> は Action<Derived> に反変です。反変性は、引数の型を逆にすることで実現されます。

サンプル比較

以下に、C#における共変性と反変性の例を示します。

共変性の例

class Animal {}
class Dog : Animal {}

IEnumerable<Dog> dogs = new List<Dog>();
IEnumerable<Animal> animals = dogs; // IEnumerable<Dog> は IEnumerable<Animal> に共変

この例では、IEnumerable<Dog> が IEnumerable<Animal> に代入可能であるため、IEnumerable<Dog> はIEnumerable<Animal> に共変です。

反変性の例

class Animal {}
class Dog : Animal {}

Action<Animal> animalAction = (Animal a) => Console.WriteLine("Animal");
Action<Dog> dogAction = (Dog d) => Console.WriteLine("Dog");

dogAction = animalAction; // Action<Dog> は Action<Animal> に反変
dogAction(new Dog()); // 出力: "Animal"

この例では、Action<Dog> がAction<Animal> に代入可能であるため、Action<Dog> はAction<Animal>に反変です。また、Action<Dog> を呼び出す際に、Dog オブジェクトを渡すことができます。しかし、animalActionがDog型の引数を受け取れないため、dogActionを呼び出すと出力は"Animal"になります。

C#,学習

Posted by hidepon