struct(値型)とclass(参照型)のコピーの違い
structは値型、classは参照型です。代入や引数渡しのたびに値そのものがコピーされるか、参照が共有されるかが変わります。
なぜエラーが出ないのか
出力: 10
(エラーなし)- C#は何も報告しません。文法として正しいためです
出力: 10- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 class Point { ^ 2 public int X; 3 } 4 class Program { 5 static void Main(string[] args) { 6 Point p1 = new Point(); 7 p1.X = 5; 8 Point p2 = p1; 9 p2.X = 10; 10 System.Console.WriteLine(p1.X); 11 } 12 }
出力: 10
structは値型なので、代入すると中身がコピーされます。p2を変更してもp1には影響しません。
直し方: class を struct にします。
広告
広告スロット(未設定)
パターン2
1 class Counter { ^ 2 public int Count; 3 public void Increment() { Count++; } 4 } 5 class Program { 6 static void Main(string[] args) { 7 Counter c1 = new Counter(); 8 Counter c2 = c1; 9 c2.Increment(); 10 System.Console.WriteLine(c1.Count); 11 } 12 }
出力: 1
c2はc1のコピーです。c2.Increment()はコピーの方だけを変更するので、c1.Countは0のままです。
直し方: class を struct にします。
パターン3
1 class Item { ^ 2 public int Price; 3 } 4 class Program { 5 static void SetPrice(Item item) { item.Price = 999; } 6 static void Main(string[] args) { 7 Item i = new Item(); 8 i.Price = 100; 9 SetPrice(i); 10 System.Console.WriteLine(i.Price); 11 } 12 }
出力: 999
メソッドに値型を渡すと、引数はコピーになります。SetPrice内での変更は呼び出し元のiに反映されません。
直し方: class を struct にします。
よくある誤解
見た目がほぼ同じclassとstructの宣言でも、コピーの意味は正反対です。変数への代入だけで挙動が変わるため、意図しない独立・共有を生みやすい部分です。
まとめ
struct(値型)とclass(参照型)のコピーの違いは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。