【図で理解】値型と参照型のメモリ構造

2026年8月27日

広告

「値型と参照型の違い」は、変数を代入したときに何がコピーされるかを見ると整理できます。まずは次の図で全体像をつかみましょう。

値型(Value Type)
a = 10
b = 10

値そのものをコピー
a と b は別々のデータ

参照型(Reference Type)
s1
s2
同じ Student
Name = “山田"

参照をコピー
s1 と s2 は同じ実体を指す

この記事では、値型と参照型の代入、変更時の挙動、初学者がつまずきやすい注意点を、C#のコードと図で確認します。

値型:値そのものがコピーされる

int a = 10;
int b = a;
b = 20;

Console.WriteLine(a); // 10
Console.WriteLine(b); // 20

b = a では、a が持つ「10」という値が b にコピーされます。その後で b を 20 に変えても、a は 10 のままです。代入後の a と b は独立しています。

代表的な値型

  • intdoubleboolchar
  • enum(列挙型)
  • struct(構造体)

注意:値型が必ず軽量とは限りません。大きな struct は、代入のたびに全フィールドがコピーされるため、コピーコストが大きくなることがあります。

参照型:同じオブジェクトへの参照がコピーされる

Student s1 = new Student { Name = "山田" };
Student s2 = s1;

s2.Name = "佐藤";

Console.WriteLine(s1.Name); // 佐藤

class Student
{
    public string Name { get; set; } = "";
}

s2 = s1 でコピーされるのは Student オブジェクトそのものではなく、そのオブジェクトを指す参照です。s1 と s2 は同じ Student を指すため、s2 経由で Name を変更すると、s1 経由で見ても「佐藤」になります。

s2.Name を変更すると…

s1 ─┐ s2 ─┘ 同じ Student
Name = “佐藤"

「スタックとヒープ」と同一視しない

学習用の図では「値型はスタック、参照型はヒープ」と説明されることがありますが、これは単純化しすぎです。値型のデータがどこに置かれるかは、ローカル変数なのか、クラスのフィールドなのか、配列の要素なのかなど、使われ方によって変わります。

まず覚えるべき本質は保存場所ではなく、代入時に、値そのものがコピーされるのか、参照がコピーされるのかです。

初学者が迷いやすい3つのポイント

1. string は参照型だが変更不可

string は参照型ですが、文字列オブジェクトは作成後に内容を変更できません(イミュータブル)。文字列を変更したように見える操作では、新しい文字列が作られて変数の参照先が変わります。そのため、数値のように独立して見えることがあります。

2. null は「何も参照していない」

参照型の変数は null を持つことがあります。これはオブジェクトが空なのではなく、変数がどのオブジェクトも指していない状態です。null のままメンバーへアクセスすると NullReferenceException が発生します。

3. コピーしても中の参照までは複製されない

オブジェクトを別に複製しても、そのフィールドが配列や別のクラスを参照している場合、内部の参照先まで自動的に複製されるとは限りません。これを「浅いコピー」と呼びます。完全に独立させたい場合は、どこまで複製するかを設計する必要があります。

Unityではどこで役立つ?

  • Vector3ColorQuaternion は struct なので値型
  • GameObjectTransformMonoBehaviour は class なので参照型
  • 複数の変数が同じ GameObject やコンポーネントを参照していれば、一方からの変更は同じ実体に反映される

たとえば Vector3 p2 = p1; では座標値がコピーされます。一方、GameObject enemy2 = enemy1; では同じ GameObject への参照がコピーされます。

まとめ

  • 値型:値そのものをコピーする
  • 参照型:オブジェクトへの参照をコピーする
  • 値型・参照型と、スタック・ヒープを同じ分類として暗記しない
  • string、null、浅いコピーは混乱しやすいので個別に確認する

確認問題

  1. int は値型・参照型のどちらでしょうか。
  2. class から作ったオブジェクトを代入すると、何がコピーされるでしょうか。
  3. 配列は値型・参照型のどちらでしょうか。
  4. string が参照型なのに値型のように見えるのはなぜでしょうか。

答え:1. 値型 2. オブジェクトへの参照 3. 参照型 4. 文字列が変更不可で、変更時に新しい文字列が作られるため

訪問数 92 回, 今日の訪問数 6回

広告

C#,参照型

Posted by hidepon