Code Fix

中級

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には影響しません。

直し方: classstruct にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン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のままです。

直し方: classstruct にします。

この問題を解いてみる →

パターン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に反映されません。

直し方: classstruct にします。

この問題を解いてみる →

よくある誤解

見た目がほぼ同じclassとstructの宣言でも、コピーの意味は正反対です。変数への代入だけで挙動が変わるため、意図しない独立・共有を生みやすい部分です。

まとめ

struct(値型)とclass(参照型)のコピーの違いは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)