【C#入門】値型と参照型は「コピーを渡すか?住所を渡すか?」で完全に理解する

2026年8月27日

広告

C#を学び始めると、値型(Value Type)参照型(Reference Type)の違いで迷うことがあります。

まず覚えてほしいポイントは、次の2つです。

  • 値型の変数を代入すると、値そのものがコピーされる
  • 参照型の変数を代入すると、同じ実体を見るための参照がコピーされる

この記事では、参照を分かりやすくするために「住所(リンク)」と表現します。ただし、これは生のメモリアドレスそのものではなく、オブジェクトを参照するための情報を表す比喩です。


1. 値型と参照型の違いは「何がコピーされるか」

どちらの場合も代入ではコピーが行われます。違うのは、コピーされるものです。

種類代入でコピーされるものコピー後の関係
値型値そのものそれぞれが独立した値を持つ
参照型オブジェクトへの参照複数の変数が同じ実体を参照できる

「値型か参照型か」は、必ずスタックかヒープかで分類するものではありません。本質は、変数が値そのものを保持するか、オブジェクトへの参照を保持するかです。

配置場所まで詳しく学びたい場合は、C#のメモリ管理入門|スタック・ヒープ・値型・参照型を初心者向けに解説を参照してください。


2. 値型:値そのものをコピーする

代表的な値型には、int、float、double、bool、char、enum、structなどがあります。

地図をコピーして渡すイメージ

あなたが持っている地図をコピーして、友人に渡したとします。友人が自分の地図に書き込んでも、あなたの地図は変わりません。2枚は同じ内容から始まりますが、コピー後は別々のものです。

int a = 5;
int b = a;  // aの値「5」をコピー

b = 10;

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

bを変更してもaが変わらないのは、2つの変数がそれぞれ独立した値を持っているからです。


3. 参照型:同じ実体への参照をコピーする

代表的な参照型には、class、配列、List、string、delegateなどがあります。

家の住所を渡すイメージ

家は1軒だけあり、あなたと友人が同じ家の住所を知っているとします。友人がその家の家具を動かせば、あなたが家を見たときにも家具は移動しています。

参照型でも「コピーされない」わけではありません。オブジェクトそのものではなく、同じオブジェクトを見るための参照がコピーされます。

class Data
{
    public int Value;
}

Data a = new Data();
a.Value = 5;

Data b = a;  // aが持つ参照をコピー
b.Value = 10;

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

abは別々の変数ですが、同じDataオブジェクトを参照しています。そのため、b経由の変更をaからも確認できます。

stringは参照型だが、値型のように見える

stringは参照型ですが、作成後の文字列の内容を変更できない不変(immutable)な型です。文字列を変更する操作では新しい文字列が作られるため、値型のように独立して見えることがあります。

詳しくは、stringは参照型なのに、なぜコピーしても影響しないの?で確認できます。


4. 図で確認:値のコピーと参照のコピー

値型では値そのものが別々の変数へコピーされ、参照型では複数の変数が同じオブジェクトを参照することを示す図

図を使ってさらに確認したい場合は、【図で理解】値型と参照型のメモリ構造もおすすめです。


5. Unityで起きやすい混乱

5-1. transform.position.xを直接変更できない理由

transform.position.x = 5; // コンパイルエラー

Vector3は構造体、つまり値型です。さらにTransform.positionはプロパティであり、取得するとVector3の値が返されます。返された一時的な値のxだけを書き換えても、変更先へ戻せないためエラーになります。

いったん変数へ取り出し、変更後の値をプロパティへ戻します。

Vector3 position = transform.position;
position.x = 5;
transform.position = position;

5-2. ScriptableObjectは参照型

ScriptableObjectは参照型なので、複数の場所が同じインスタンスを参照していると、一方から行った変更をほかの場所からも確認できます。

ただし、「参照型だから変更が必ずアセットへ永続保存される」という意味ではありません。Editor上のアセット、再生中に生成したインスタンス、ビルドしたアプリでは扱いが異なります。保存されるかどうかは、どのインスタンスを変更したか、Editorのシリアライズ対象か、明示的な保存処理を行ったかによって決まります。


6. 確認問題

  1. int b = a;の後でbを変更しました。aも変わりますか?
  2. Player b = a;の後でb.Hpを変更しました。a.Hpからも変更を確認できるのはなぜですか?
答えを確認する

1. 変わりません。値そのものがコピーされ、別々の値になるからです。
2. abが、同じPlayerオブジェクトへの参照を持っているからです。


7. まとめ

  • 値型:値そのものがコピーされ、コピー後は独立する
  • 参照型:参照がコピーされ、複数の変数が同じ実体を参照できる
  • 「住所」は理解のための比喩であり、生のメモリアドレスそのものではない
  • 値型/参照型の違いと、スタック/ヒープの配置は分けて考える

newとの関係まで学びたくなったら、C#のnewを理解する――値型・参照型・スタック・ヒープの関係へ進んでください。

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

広告

C#,参照型

Posted by hidepon