C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#の共変性と反変性とは?初心者向けに基本概念をわかりやすく解説

はじめに

C#でクラスを効果的に扱うためには、「共変性」と「反変性」という概念を理解しておくことが非常に役立ちます。これらは一見とっつきにくい言葉ですが、仕組みをつかめば型の扱いがぐっと柔軟になり、コードの再利用性も高まります。

継承関係を持つサンプルクラス

まずは、以下のように3つのクラスを定義してみましょう。「Two」は基底クラス「One」を継承した派生クラスであり、さらに「Three」は「Two」を継承しています。

class One { 
}
class Two: One {
}
class Three : Two { 
}

つまり、継承の階層は「One → Two → Three」という順序になっています。

共変性とは何か

C#では、基底クラス型の変数には派生クラスのインスタンスを代入できるのが基本ルールですが、その逆(派生クラス型の変数に基底クラスのインスタンスを入れる)ことはできません。

// 共変性の例:派生クラスのインスタンスを基底クラス型に代入できる
One obj = new Three();

この原則をもとに、共変性とは「基底型が期待される場面で、派生型を渡すことを可能にする機能」を指します。

共変性は、C#のさまざまな要素に適用でき、代表的なものとしては次のようなものがあります。

  • 配列
  • インターフェース(out キーワードによるジェネリック型パラメータ)
  • デリゲート

反変性とは何か

一方、反変性は主にメソッドのパラメータに関わる概念です。反変性を利用すると、「基底クラスをパラメータとして受け取るメソッド」を、「派生クラスをパラメータとして期待するデリゲート」に割り当てることができます。

delegate void MyDelegate(Three t);

static void Handle(One o) { }

MyDelegate d = Handle; // 反変性により、この代入が許可される

このように、より広い型(基底クラス)を受け取れるメソッドであれば、より狭い型(派生クラス)を要求するデリゲートにも安全に対応できるため、柔軟なメソッド設計が可能になります。

まとめ

  • 共変性: 基底型が期待される場所に派生型を渡せる。配列・インターフェース・デリゲートなどで活用できる。
  • 反変性: 基底クラスをパラメータに持つメソッドを、派生クラスを期待するデリゲートに割り当てられる。

共変性と反変性を正しく理解すれば、ジェネリックやデリゲートを使った設計の幅が大きく広がります。ぜひ実際のコードでも試してみてください。

  1. Javaのクラス変数(静的変数)とは?仕組みと使い方をサンプルコードで解説

    Javaにおけるクラス変数は「静的変数(static変数)」とも呼ばれ、メソッドの外側で static キーワードを使って宣言される変数です。 静的変数の最大の特徴は、そのクラスのすべてのインスタンス(オブジェクト)で値が共有されるという点です。変数のコピーはメモリ上に1つだけ存在し、すべてのオブジェクトが同じ値を参照します。 静的変数の主な特徴 static キーワードを付けて宣言する メソッドの外側(クラス直下)に定義する 全インスタンスで1つのコピーを共有する オブジェクトを生成しなくても「クラス名.変数名」でアクセスできる サンプルコード public class Demo{

  2. Pythonの例外基本クラス徹底解説|BaseExceptionと例外階層、独自例外の作り方

    Pythonにおける例外とは Pythonには、他の高水準言語と同様に例外(Exception)の仕組みが備わっています。プログラムの実行中に問題が検出されると例外が発生(raise)し、適切に処理しなければプログラムはその時点で中断されます。代表的な例外には、ゼロ除算を表すZeroDivisionErrorや、アサーションの失敗を表すAssertionErrorなど、さまざまな種類があります。 すべての例外クラスはBaseExceptionクラスから派生しています。開発者は組み込みの例外をそのまま利用できるだけでなく、raise文を使ってコード中で意図的に例外を発生させることもできます。さら