一開始看到 record,其實完全抓不到重點
看起來跟 class 很像,而 class 又早就被拿來跟 struct 比過無數次
現在再多一個 record,第一反應只覺得,是不是又一個學了也不一定會用到的語法糖..
直到後來真的去看它的定義,也在實際情境中用過之後,
我才發現 record 關心的重點是"這份資料從一開始就不該被改"
下面整理兩個我後來才想清楚的重點
1. 一開始真正讓我搞懂 record 的,其實是這種比對情境。
在 API 接收物件裡,我在意的從來不是是不是同一個 instance,
而是"這兩筆資料是不是代表同一件事"。
record 預設用資料內容來判斷相等,只要欄位值一樣,用 == 就會是 true。
而一旦你透過 with 產生新資料,只要其中一個值不同,這件事情在實務上很直覺
public record ApiReceiveObject(string id, string name, int age);
var a = new ApiReceiveObject("1", "Donma", 29);
var b = new ApiReceiveObject("1", "Donma", 29);
var result = a == b; // true
Console.WriteLine(result); // true
var updatedB = b with { age = 31 };
Console.WriteLine(b==updatedB); // false
2.當然你也可以把 record 寫得很像 class,
但你要很清楚,這代表你刻意選擇放棄限制,資料可以被修改
record 剩下的價值,只剩下 "內容一樣就算一樣"
如果這正是你要的,那這樣寫完全合理
只是失去 record 會幫你多做任何保護
public record TestRecord1
{
public string Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
var a = new TestRecord1 { Id = "1", Name = "Donma", Age = 29 };
var b = new TestRecord1 { Id = "1", Name = "Donma", Age = 29 };
Console.WriteLine(a == b); // true
b.Age = 31;
Console.WriteLine(a == b); // false
簡單結論,如果只看語法,record 跟 class 其實差不了多少
真正的差別,在於你希望這份資料在系統裡扮演什麼角色
record 用得好,會讓資料定義變得很清楚
但用得隨意,它最後只會剩下一個比較聰明的 Equals
所以重點從來不是關鍵字本身
而是你怎麼看待這個物件是拿來做什麼的
當你想清楚這件事,record 帶來的方便性才會真正出現
--
本文原文首發於個人部落格:[C#] record 與 class 的真正差別,其實不在語法
--
---
The bug existed in all possible states.
Until I ran the code.