Code Fix

上級

record と class で == の結果が変わる理由

recordはプロパティの値が全て同じなら==がtrueになる値ベースの等価性を自動生成します。classは既定で参照ベースの等価性のままです。

なぜエラーが出ないのか

出力: False
(エラーなし)
C#は何も報告しません。文法として正しいためです
出力: False
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  class     Point(int X, int Y);
        ^
 2  class Program {
 3      static void Main(string[] args) {
 4          Point a = new Point(1, 2);
 5          Point b = new Point(1, 2);
 6          System.Console.WriteLine(a == b);
 7      }
 8  }
出力: False

recordは既定で値(プロパティの中身)を比較する==を自動生成します。classは参照を比較するので、同じ値でもfalseになります。

直し方: classrecord にします。

この問題を解いてみる →

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

パターン2

 1  class     Money(decimal Amount, string Currency);
        ^
 2  class Program {
 3      static void Main(string[] args) {
 4          Money a = new Money(1000, "JPY");
 5          Money b = new Money(1000, "JPY");
 6          System.Console.WriteLine(a == b);
 7      }
 8  }
出力: False

金額のように「値」として扱いたいデータはrecordにすると、比較のたびにEqualsを書かずに済みます。

直し方: classrecord にします。

この問題を解いてみる →

パターン3

 1  class     Range(int Start, int End);
        ^
 2  class Program {
 3      static void Main(string[] args) {
 4          Range a = new Range(0, 10);
 5          Range b = new Range(0, 10);
 6          System.Console.WriteLine(a == b);
 7      }
 8  }
出力: False

区間のような不変のデータもrecordに向いています。プロパティが全て同じなら等しいと判定されます。

直し方: classrecord にします。

この問題を解いてみる →

よくある誤解

見た目がほとんど同じrecordとclassの宣言でも、==の意味は正反対になります。値として比較したいデータ構造にはrecordが向いています。

まとめ

record と class で == の結果が変わる理由は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

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