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になります。
直し方: class を record にします。
広告
広告スロット(未設定)
パターン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を書かずに済みます。
直し方: class を record にします。
パターン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に向いています。プロパティが全て同じなら等しいと判定されます。
直し方: class を record にします。
よくある誤解
見た目がほとんど同じrecordとclassの宣言でも、==の意味は正反対になります。値として比較したいデータ構造にはrecordが向いています。
まとめ
record と class で == の結果が変わる理由は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。