[小菜一碟] C# 9 對 Immutable(不可變)物件有了更好的支援

在先前的 Akka.NET 直播中有提到一個原則「訊息(Message)是不可變的」,剛好 C# 9 的新語法 initrecord,可以輔助我們更方便地建立不可變物件,我們就來一起看一下這兩個新語法怎麼使用?

init

init 語法其實是把我們原先在定義 Property 時的 set 語法換成 init,一旦換成 init 之後,這個 Property 的值就只能被 set 一次,之後就不能改了,藉此達到了不可變的效果。

public class MyImmutable
{
    public int Id { get; init; }

    public string Name { get; init; }
}

如果我們執意要修改 init 的 Property,在設計時期編輯器就會提出警告。

record

record 是一個新型的 class 類型,它是個 Reference Type,但是卻具有 Value Type 的特性,兩個 record 物件在做比較的時候,內部是在做值比對,Bill 叔有一篇文章在介紹 record 語法背後的魔法,大家可以去看看。

我們用 record 簡化的宣告語法所宣告出來的屬性,本身就是 init Property,省去我們對 Property 逐一宣告 init 的步驟。

public record MyRecord(int Id, string Name);

上面的宣告語法等同於:

public record MyRecord
{
    public MyRecord(int id, string name)
    {
        this.Id = id;
        this.Name = name;
    }

    public int Id { get; init; }

    public string Name { get; init; }
}

另外,它還保留了宣告可變屬性的彈性,也就是說 record 類別的屬性不一定都是不可變的,也可以是可變的。

public record MyRecord(int Id, string Name)
{
    public string Address { get; set; }
}

C# 9 的 record 語法可說是在建立不可變物件這件事情上,起了最大的幫助,是一個甜度超高的語法糖。

參考資料

C# 指南ASP.NET 教學ASP.NET MVC 指引
Azure SQL Database 教學SQL Server 教學Xamarin.Forms 教學