在 C# 物件導向程式設計中,屬性的 get 與 set 訪問器可以獨立設置存取層級,這為實現封裝與資料保護提供了強大靈活性。初學者常見疑惑:private set 與無修飾符的 set 究竟有何不同?為何 get 通常不設為 private?
| 聲明方式 | 類內部 | 類外部 | 典型應用場景 |
|---|---|---|---|
public int Age { get; set; } | 可讀可寫 | 可讀可寫 | 普通資料傳輸物件 (DTO) |
public int Id { get; private set; } | 可讀可寫 | 唯讀 | 實體識別碼、建構子注入後凍結 |
private int Counter { get; set; } | 可讀可寫 | 不可見 | 內部狀態追蹤 |
get 通常保持公共?get 代表「查詢」,set 代表「變更」。領域驅動設計 (DDD) 強調「命令查詢分離」:外部物件應能查詢狀態,但變更狀態需透過明確的領域方法(如 ChangeAddress()),而非直接設值。若 get 設為 private,外部連查詢權限都失去,物件變成「黑盒」,違背資訊揭露原則。
C# 9.0 引入 init 訪問器:
public record User(string Name, int Age)
{
public string Email { get; init; } // 物件初始化器可設,之後唯讀
}
這比 private set 更語義化,配合 record 類型可自動獲得不可變性與值語義。
get; init; 或 get; private set; 實現不可變資料。Rename()、Activate()),內部再呼叫 private set。public set 暴露內部表達,導致不變條件 (invariant) 破壞。掌握訪問器層級控制,是編寫健壯、可維護 C# 程式碼的關鍵基礎。