“参照型”と“値型”をテレビのたとえで一気に理解する C# メモリモデル講座

リモコン派? 本体派?

対象: C# を学び始めたばかりの人

この記事でわかること

  1. 参照型 (reference type) と 値型 (value type) の違い
  2. コピー・格納・破棄がどう変わるか
  3. どちらを選べば失敗しにくいか

1. まず用語を整理しよう

分類主な宣言キーワード・例特徴
参照型(reference type)class, interface, delegate, 配列 int[], string など変数は ヒープ上のオブジェクトへのアドレス を保持。実体は 1 か所、ガベージコレクション (GC) の対象
値型(value type)struct, enum, 組み込み数値型 int, double, bool, char など変数が データ本体 をそのまま保持。代入すると丸ごと複製される

✔︎ ポイント

  • class は「参照型を宣言するためのキーワードの一つ」であって “参照型=class” ではありません
  • struct や enum を使うと「値型」を宣言できる

2. 参照型は “テレビ + リモコン”

構成要素たとえ振る舞い
変数テレビの リモコンリモコン本体は小さく、ボタンを押すと本体が動く
オブジェクトテレビ本体実体は家に 1 台だけ。リモコンが何個あっても共有
コピーリモコンをもう 1 台配るどのリモコンから操作しても同じテレビが反応
エラーテレビの電源コードを抜くと全リモコンが無力C# では null 参照例外 (NullReferenceException)

コードで体験

class Television
{
    public int Volume { get; set; }
}

var tvA = new Television { Volume = 5 };
var tvB = tvA;      // リモコンをもう 1 個

tvB.Volume = 10;    // どのリモコンでも同じテレビ
Console.WriteLine(tvA.Volume); // 10

3. 値型は “テレビ本体を机にドン!”

構成要素たとえ振る舞い
変数前面操作パネル付きテレビ本体変数そのものがテレビを抱える
コピーテレビをまるごと複製して隣に置く操作は完全に独立、干渉しない
破棄テレビを机からどければ終わりスコープを抜ければ自動回収 (GC 不要)

コードで体験

struct FrontPanelTv
{
    public int Volume { get; set; }
}

var fpA = new FrontPanelTv { Volume = 5 };
var fpB = fpA;      // 本体を箱ごとコピー

fpB.Volume = 10;    // 独立した 2 台目
Console.WriteLine(fpA.Volume); // 5

4. 参照型 vs 値型 ── 一覧で比較

特性参照型 (class など)値型 (struct など)
格納先変数はアドレス、実体はヒープ変数内に実体を直格納
コピーアドレス複製 → 同じオブジェクト共有データ丸ごと複製 → 独立オブジェクト
GC の影響ヒープ解放は GC 任せスタック領域はスコープで自動消滅
== 既定参照比較値比較 (フィールドごと)
null 許容あり基本なし (T? で nullable にできる)
適材適所複雑・可変なデータ/共有したいとき小さくて不変なデータ/多数扱うとき

5. 選び方のチェックリスト

質問YESNO
データは 16 byte 以下 & 変更不可?値型で OK参照型を検討
同じデータを複数場所で共有したい?参照型にすべき値型でも可
GC 圧迫を絶対に避けたい?値型を優先参照型でも問題なし
ボックス化 (object への暗黙変換) が起きる?参照型に切り替え値型のままでも可

6. まとめ

  • 参照型 = リモコン方式
    • 変数は小さいアドレスだけ
    • コピーは軽いが null と競合に注意
  • 値型 = 本体直置き方式
    • コピーが重い可能性はあるが独立性が高い
    • 小さく不変なら最高に高速

覚え方

  • リモコンが要るのが参照型
  • 机に直置きが値型

これさえ頭に入れておけば、C# のメモリモデルで迷子になることはありません。

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