本文要介紹的是 C# 9 增加的 init-only setters 語法。
僅供初始化的設定子(init-only setters)是用來限定某個屬性只能在物件初始化的過程中賦值。也就是說,只有以下這幾個地方才可以設定 init-only 屬性的初始值:
- 建構式(constructor)
- 屬性初始設定式(property initializer)
- 物件初始設定式(object initializer)
其他地方則不允許修改那個屬性的內容。
如要限定某個屬性只能在物件初始化的過程中賦值(即 init-only 屬性),只要在宣告屬性的時候把關鍵字 set
改為 init
即可。參考以下範例:
class Student
{
public int Id { get; init; } = 1; // OK!
public Student()
{
Id = 2; // OK!
}
}
說明:
- 第 3 行:宣告
Id
屬性為 init-only,並以屬性初始設定式來將 初始值設定為 1。 - 第 7 行:在建構式當中設定
Id
屬性值為 2。
以下範例則是透過物件初始設定式來賦值:
var john = new Student { Id = 3 }; // OK!
john.Id = 2; // 編譯失敗! 不可修改此屬性值。
唯讀屬性與 init-only 屬性的行為類似,但唯讀屬性有個缺點:如果透過建構式的參數來設定初始值,可能會增加日後修改的麻煩。例如:
class Student
{
public int Id { get; };
public Student(int id)
{
Id = id;
}
}
如上例所示,外界如果要設定唯讀屬性的值,唯一途徑是透過物件的建構式。然而,此做法有個缺點:日後如果要替建構式增加新的參數,將連帶影響所有用戶端程式碼(必須修改程式,否則無法編譯)。若要避免這些麻煩,就只能在給建構式增加參數的時候提供參數的預設值。現在有了 init-only 屬性,就不用再糾結了:它不僅具有唯讀屬性的好處,而且外界可以透過物件初始設定式來設定這些 init-only 屬性的初始值。
備註:init-only 屬性還有一個用處,是跟
record
型別一起搭配使用。這個部分請參考另一篇筆記:〈C# 9:Record 詳解〉。
Happy coding!
沒有留言: