【図で理解】値型と参照型のメモリ構造
「値型と参照型の違い」は、変数を代入したときに何がコピーされるかを見ると整理できます。まずは次の図で全体像をつかみましょう。
値そのものをコピー
a と b は別々のデータ
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 は独立しています。
代表的な値型
int、double、bool、charenum(列挙型)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 を変更すると…
Name = “佐藤"
「スタックとヒープ」と同一視しない
学習用の図では「値型はスタック、参照型はヒープ」と説明されることがありますが、これは単純化しすぎです。値型のデータがどこに置かれるかは、ローカル変数なのか、クラスのフィールドなのか、配列の要素なのかなど、使われ方によって変わります。
まず覚えるべき本質は保存場所ではなく、代入時に、値そのものがコピーされるのか、参照がコピーされるのかです。
初学者が迷いやすい3つのポイント
1. string は参照型だが変更不可
string は参照型ですが、文字列オブジェクトは作成後に内容を変更できません(イミュータブル)。文字列を変更したように見える操作では、新しい文字列が作られて変数の参照先が変わります。そのため、数値のように独立して見えることがあります。
2. null は「何も参照していない」
参照型の変数は null を持つことがあります。これはオブジェクトが空なのではなく、変数がどのオブジェクトも指していない状態です。null のままメンバーへアクセスすると NullReferenceException が発生します。
3. コピーしても中の参照までは複製されない
オブジェクトを別に複製しても、そのフィールドが配列や別のクラスを参照している場合、内部の参照先まで自動的に複製されるとは限りません。これを「浅いコピー」と呼びます。完全に独立させたい場合は、どこまで複製するかを設計する必要があります。
Unityではどこで役立つ?
Vector3、Color、Quaternionは struct なので値型GameObject、Transform、MonoBehaviourは class なので参照型- 複数の変数が同じ GameObject やコンポーネントを参照していれば、一方からの変更は同じ実体に反映される
たとえば Vector3 p2 = p1; では座標値がコピーされます。一方、GameObject enemy2 = enemy1; では同じ GameObject への参照がコピーされます。
まとめ
- 値型:値そのものをコピーする
- 参照型:オブジェクトへの参照をコピーする
- 値型・参照型と、スタック・ヒープを同じ分類として暗記しない
- string、null、浅いコピーは混乱しやすいので個別に確認する
確認問題
intは値型・参照型のどちらでしょうか。classから作ったオブジェクトを代入すると、何がコピーされるでしょうか。- 配列は値型・参照型のどちらでしょうか。
stringが参照型なのに値型のように見えるのはなぜでしょうか。
答え:1. 値型 2. オブジェクトへの参照 3. 参照型 4. 文字列が変更不可で、変更時に新しい文字列が作られるため





ディスカッション
コメント一覧
まだ、コメントがありません