C#のクラスは参照型──コンパイル時の分類と実行時の挙動

はじめに

C#では class で定義した型を「参照型(reference type)」と呼びます。しかし、実際にオブジェクトが作られて参照が変数に入るのはプログラム実行時の new 演算子による割り当て時です。本記事では「参照型」という言葉の意味と、コンパイル時・実行時のそれぞれで何が起きているのかを解説します。


1. 参照型とは何か?

  • 言語仕様上の分類
    • C#の型は「値型(value type)」と「参照型」に大きく分かれます。
    • struct や数値型・列挙型などは値型、class や配列、文字列は参照型に分類されます。
  • 参照型の振る舞い
    • 変数には「オブジェクトを格納したヒープ領域のアドレス(参照)」が保持される
    • 代入やメソッド呼び出し時には参照がコピーされ、同じオブジェクトを複数の変数が指すことが可能

2. コンパイル時に決まる「参照型」の属性

  1. 型チェックと最適化
    • コンパイラはソースコード解析の段階で、各型が値型か参照型かを把握
    • 参照型に対しては null チェックやボクシング/アンボクシングのルールが適用
  2. IL(中間言語)レベルでも区別
    • コンパイル後のILコード上でも値型はスタック操作、参照型はオブジェクト参照操作として扱われる
  3. 実行前に「参照を保持する型」という性質は確定
    • 新しくコードを書いたり、ライブラリを読み込んだりしても、この分類は変わらない

3. 実行時に初めて「参照」が実体化される

  • 変数宣言だけではヒープに何もない
Person p;   // p はまだ null。ヒープ領域にはオブジェクトなし
  • new でオブジェクト生成→参照を取得
p = new Person { Name = "太郎" };
// CLRがヒープにPersonオブジェクトを割り当て、その参照をpに格納
  • 参照のコピーで同一オブジェクトを共有
Person q = p;   // q も同じオブジェクトを指す
q.Name = "次郎";
Console.WriteLine(p.Name);  // "次郎" と表示される
タイミング起きていること
コンパイル時Person が参照型と分類され、ILコード上の扱いが決まる
実行時(宣言)Person p; → 変数は null (参照先なし)
実行時(生成)new Person(…) → ヒープにオブジェクト生成・参照を変数に格納

4. まとめ

  • 「参照型」はあくまで型の分類
    • どの型が参照型かはコンパイル時に決まる
  • オブジェクト生成と参照の取得は実行時の処理
    • new 演算子で初めてヒープ領域に実体化し、変数に参照が入る
  • 実行前に振る舞いのイメージは決まっている
    • 変数宣言だけでは null であり、参照型であるという性質だけが保証される

C#における「参照型」は、コンパイル時に決まる「変数がオブジェクトへのポインタを保持する型」という仕様的分類と、実行時に new で実体化してはじめて参照が具現化される、という二段階の概念で成り立っています。プログラムを正しく理解し、デバッグや設計に活かしましょう。

訪問数 3 回, 今日の訪問数 3回