C# record(紀錄) 介紹

class 示範

在 C# 中,我們可以使用 class 關鍵字來自訂物件,例如定義具有 Id 和 Name 兩個屬性的 User 類別:
    
    public class User
    {
        public int Id;
        public string Name;
    }
    

實例化物件:
    
        var user = new User()
        {
            Id = 1,
            Name = "小明",
        };
    

record 示範

除了 class 外,我們也可以使用 record 關鍵字來定義一個以值為基礎的類型
    
public record User(int Id, string Name);
    

實例化物件:
    
var user = new User(1, "小明");
    

在上面的定義中,User 的屬性是不可以變更(Immutability)的,因為在預設宣告時已經自動加入 init-only 屬性,如果想要改變就會拋出例外:
    
var user = new User(1, "小明");

user.Id = 2;
// Init-only property 'User. Id' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor
    

讓 record 屬性值可以被更新

上面說 record 的屬性值不可以更新,但是這不是絕對的,而是指預設情況,還是有方法能夠讓 record 被改變:
    
	// 定義可以被改變值的 record 類型
    public record User
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    // 實例化
    var user = new User()
    {
        Id = 1,
        Name = "小明",
    };
    
    // 可以改變值而不會遇到錯誤
    user.Id = 2;
    

針對屬性顯示最佳化的 ToString 方法

平時將資料印出時會自動呼叫 ToString 方法,平時直接執行類別的 ToString 方法會回傳 物件的命名空間和類別名稱:
    
    var user = new User()
    {
        Id = 1,
        Name = "小明",
    };
    
    Console.WriteLine(user.ToString());
    // ConsoleAppRecordTest0824.Program+User
    

而針對 record,ToString 方法會使用以下格式回傳: 類型名稱 { 屬性 = 值, 屬性 = 值 }
    
// public record User(int Id, string Name);
var user = new User(1, "小明");
    
Console.WriteLine(user.ToString());
// User { Id = 1, Name = 小明 }
    

物件比較

對於 class 的比較,會比較兩者的記憶體位置是否相等,而對於 record 則會比較兩者的類型和值,只要內容一樣就會回傳 True
    
        var user1 = new User(1, "小明");
        var user2 = new User(1, "小明");
        Console.WriteLine(user1 == user2); // True
    

在上面的範例中 User 是 record ,如果是 class 則會是 False

解構賦值

相比於 class,record 還有一個很棒的地方,可以使用元組(Tuple)的解構賦值方式來將 record 的資料取出,但是僅限於使用括號宣告的類型:
    
// public record User(int Id, string Name);

var user = new User(1, "小明");
var (id, name) = user;

Console.WriteLine($"id: {id}, name: {name}");
// id: 1, name: 小明
    



參考資料:
Microsoft.Learn - Records (C# reference)
Microsoft.Learn - Create record types
Microsoft.Learn - Deconstructing tuples and other types

留言

張貼留言

如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com