在 C# 中,屬性 是封裝類別內部資料的核心機制。相較於直接公開欄位,屬性透過 get(讀取)與 set(寫入)存取子,提供資料驗證、延遲計算、事件通知等彈性。本文詳細說明三種屬性模式(唯讀、唯寫、讀寫)的語法與實務應用,並附上完整可執行範例。
| 模式 | 關鍵字組合 | 適用情境 |
|---|---|---|
| 唯讀 | get only | 計算屬性、常數、不可變物件狀態 |
| 唯寫 | set only | 密碼設定、單向資料流、注入相依性 |
| 讀寫 | get / set | 一般資料封裝、雙向綁定 |
using System;
public class DemoClass
{
// 私有備份欄位
private int _writeOnlyField;
private readonly int _readOnlyField = 100;
private int _readWriteField;
// 唯寫屬性:僅提供 set 存取子
public int WriteOnlyProperty
{
set { _writeOnlyField = value; }
}
// 唯讀屬性:僅提供 get 存取子
public int ReadOnlyProperty
{
get { return _readOnlyField; }
}
// 讀寫屬性:同時提供 get 與 set
public int ReadWriteProperty
{
get { return _readWriteField; }
set { _readWriteField = value; }
}
}
class Program
{
static void Main()
{
DemoClass obj = new DemoClass();
// 唯讀:只能取值
int val = obj.ReadOnlyProperty; // 100
Console.WriteLine($"ReadOnly: {val}");
// 唯寫:只能指派
obj.WriteOnlyProperty = 250;
// 無法讀取 obj.WriteOnlyProperty → 編譯錯誤
// 讀寫:可讀可寫
obj.ReadWriteProperty += 10_000_000;
Console.WriteLine($"ReadWrite: {obj.ReadWriteProperty}"); // 10000000
}
}
在 set 區塊中,value 代表呼叫端指派的值,型別與屬性宣告一致。可在其中加入驗證邏輯:
public int Age
{
set
{
if (value < 0 || value > 150)
throw new ArgumentOutOfRangeException(nameof(value), "年齡需在 0~150 之間");
_age = value;
}
}
// 傳統寫法:唯讀欄位 + get 存取子
private readonly int _id = 42;
public int Id { get { return _id; } }
// C# 6+ 唯讀自動實作屬性(編譯器自動產生 readonly backing field)
public int Id { get; } = 42;
// 建構子指派(C# 6+)
public int Id { get; }
public DemoClass(int id) => Id = id;
public string Password { set => _hashed = Hash(value); }public ILogger Logger { set => _logger = value; }public Action OnSave { set => _saveHandler += value; }// C# 6+ 簡潔語法
public int ReadOnly => _readOnlyField;
public int ReadWrite { get => _field; set => _field = value; }
C# 允許 get 與 set 設定不同存取層級:
public int InternalId { get; private set; } // 外部可讀,內部可寫
public int ProtectedData { get; protected set; } // 衍生類別可寫
public int Prop { get; set; }),需要邏輯時再展開完整寫法。GetData())表達語意。get only,透過建構子初始化,利於執行緒安全。