單例模式確保類別僅有一實例並提供全域存取點。C#/.NET 提供多種實現路徑,各有權衡。
public class Singleton {
private static Singleton _instance;
private Singleton() {}
public static Singleton Instance {
get {
if (_instance == null) _instance = new Singleton();
return _instance;
}
}
}
❌ 多執行緒下可能建立多實例
public sealed class Singleton {
private static readonly Singleton _instance = new();
private Singleton() {}
public static Singleton Instance => _instance;
}
sealed 防繼承破壞單例語義
public class SingletonProvider where T : new() {
private SingletonProvider() {}
public static T Instance => SingletonCreator.Instance;
private class SingletonCreator {
static SingletonCreator() {}
internal static readonly T Instance = new T();
}
}
// 使用:SingletonProvider.Instance
T 獨立單例
public sealed class Singleton {
private static volatile Singleton _instance;
private static readonly object _sync = new();
private Singleton() {}
public static Singleton Instance {
get {
if (_instance == null) {
lock (_sync) {
if (_instance == null) _instance = new Singleton();
}
}
return _instance;
}
}
}
volatile 防指令重排lock(_sync) 專用同步物件(非 this)
public sealed class Singleton {
private static readonly Lazy _lazy = new(() => new Singleton());
private Singleton() {}
public static Singleton Instance => _lazy.Value;
}
LazyThreadSafetyMode.ExecutionAndPublication(預設)全執行緒安全| 場景 | 推薦版本 | 理由 |
|---|---|---|
| 一般單例 | 版本二 (static readonly) | 最簡、最快、CLR 原生保證 |
| 需參數化建構/條件建立 | 版本五 | Lazy 支援工廠委派、例外處理 |
| 多型別單例工廠 | 版本三 | 泛型復用、獨立生命週期 |
| 教學/跨語言對比 | 版本四 | 展示記憶體模型細節 |
單例非銀彈:優先考慮依賴注入 (DI) 管理單例生命週期(services.AddSingleton<IService, Service>()),避免全域狀態耦合、難測試、難替換。