| 方式 | 語法 | 執行時機 | 異常處理 | 適用場景 |
|---|---|---|---|---|
| 靜態欄位初始化器 | static int X = Compute(); | 類別首次被存取前、靜態建構函式**之前** | **無法 try-catch**,異常會包裝為 TypeInitializationException 拋出 | 簡單、無副作用、無異常風險的值型別/字串常數 |
| 靜態建構函式 | static MyClass() { X = Compute(); } | 類別首次被存取時、欄位初始化器**之後** | ✅ **可完整 try-catch**,可記錄日誌、提供預設值、避免整個應用程式崩潰 | 複雜邏輯、IO/網路/資料庫存取、可能拋出異常、需特定順序初始化 |
public sealed class Singleton
{
private static readonly Singleton _instance;
static Singleton() => _instance = new Singleton(); // 靜態建構函式初始化
public static Singleton Instance => _instance;
private Singleton() { } // 私有建構函式防止外部 new
}
優點:簡潔、執行緒安全、Lazy (首次存取才建立)、無雙重檢查鎖定複雜度。
class A { public static int X = B.Y + 1; static A() { X++; } }
class B { public static int Y = A.X + 1; static B() { Y++; } }
// 輸出 A.X, B.Y 為何?
// 1. 存取 A.X → 初始化 A
// 2. A.X 欄位初始化器:需 B.Y → 初始化 B
// 3. B.Y 欄位初始化器:需 A.X → A 正在初始化中,**直接讀取預設值 0** → Y = 1
// 4. B 靜態建構函式:Y++ → Y = 2
// 5. 回到 A:X = B.Y(2) + 1 = 3
// 6. A 靜態建構函式:X++ → X = 4
// 結果:A.X = 4, B.Y = 2
static readonly int Max = 100;。try-catch,失敗時記錄日誌並設定安全預設值。Lazy<T> 實作。
private static readonly Lazy _resource =
new Lazy(() => new HeavyResource(), LazyThreadSafetyMode.ExecutionAndPublication);
public static HeavyResource Resource => _resource.Value;
掌握靜態初始化順序與異常處理,配合靜態建構函式或 Lazy<T>,即能建立健壯的靜態狀態管理。