e1 と e2 は同じ敵だった――var e2 = e1; で学ぶ C# 参照コピーの仕組み
var e2 = e1; は オブジェクトを複製 するのではなく、参照値(アドレス)をコピーするだけ。結果として「Enemy インスタンスは 1 つ、変数は 2 つ」という状態になる。
目次
1. まずはコードを確認
var e1 = new Enemy(); // Enemy インスタンスを生成
var e2 = e1; // 参照をコピー

上のイラストで、e1 と e2 が同じ Enemy インスタンスを指しているメモリ構造がひと目で分かります。スタック上の変数(e1・e2)は矢印だけを持ち、ヒープ上のオブジェクトは 1 個──まさに「オブジェクトは 1 つ、参照は 2 つ」です。
ステップ | 実行内容 | メモリのイメージ |
---|---|---|
① new Enemy() | ヒープ領域に Enemy が 1 つ確保される | ヒープ: [Enemy] |
② e1 に代入 | スタック上のローカル変数 e1 に、Enemy への参照値が入る | e1 ➜ [Enemy] |
③ e2 = e1 | 参照値をコピー。e2 も同じアドレスを指す | e1 ➜ [Enemy]e2 ➜ [Enemy] |
e1.Health = 10;
Console.WriteLine(e2.Health); // => 10
e1 も e2 も同じオブジェクトを見ているため、片方のプロパティ変更はもう片方にも反映されます。
2. 参照型 vs. 値型 ――この違いがキモ
特性 | 参照型 (class) | 値型 (struct) |
---|---|---|
どこに格納? | ヒープ(実体) + スタック(参照) | スタック or ヒープ(Box化) |
代入時の挙動 | アドレスをコピー | 内容をコピー |
共有可否 | 複数変数で同一インスタンスを共有 | コピー先は独立した別オブジェクト |
値型の代入は“写し”を作るのに対し、参照型は“同じものを指す矢印”を配るイメージです。
3. ガベージコレクションに注意
- .NET の GC は「参照カウント」ではなく 到達不能判定。
- したがって
e1 = null; // e2 はまだ生きている
- の場合、Enemy インスタンスは回収されません。すべての参照が途切れて初めて GC の対象になります。
4. デバッグで“同じもの”かどうかを確かめる
- ウォッチ式で比較
e1 == e2 // true なら同一インスタンス
- ハッシュコードを出力
Console.WriteLine(RuntimeHelpers.GetHashCode(e1));
Console.WriteLine(RuntimeHelpers.GetHashCode(e2));
- 2 行が同じ数値を示せば、内部的なアドレス(オブジェクト ID)が同一です。
5. 初学者がハマりやすいポイントと対策
ありがちな誤解 | 実際には… | 早めに教えたいコツ |
---|---|---|
e2 = e1 で「コピーしたから別物」という思い込み | 参照値コピーなので同一オブジェクト | 図解で“矢印が 2 本”のイメージを示す |
e1 を null にすればメモリ解放される | 他の参照がある限り GC されない | “参照が 0 本になって初めて回収”を強調 |
struct でも同じ動きと思ってしまう | 値型は 内容コピー(別インスタンス) | Point p1 = p2; と p1.X = … の例で違いを実演 |
6. まとめ
- 参照型の代入は“アドレス伝言”。オブジェクトの数は増えない。
- 値型は“実体コピー”。独立した箱ができる。
- GC は到達不能になったとき初めて回収。1 本でも参照が残っていれば生き続ける。
- デバッグ時は == 比較や RuntimeHelpers.GetHashCode() で同一インスタンスか確認できる。
付録:ワンポイント練習問題
- 下のコードを実行したとき、最後に表示される値は?
var e1 = new Enemy { Health = 100 };
var e2 = e1;
e2.Health = 50;
Console.WriteLine(e1.Health); // ???
- 値型 struct Position { public int X; } を使い、p1 と p2 が独立していることを示すコードを書け。
- 50…同一インスタンスを指しているため。
- p1.X = 1; Console.WriteLine(p2.X); // 0 などで確認。
これで「参照コピーの仕組み」が腑に落ちれば幸いです。
訪問数 5 回, 今日の訪問数 5回
ディスカッション
コメント一覧
まだ、コメントがありません