單例模式是最常用的設計模式之一,但每次為新類別實現單例都要寫一遍樣板碼:私有建構函式、靜態實例欄位、執行緒安全的雙重檢查鎖定……這不僅繁瑣,還容易出錯。C# 2.0 引入泛型後,我們可以將單例邏輯提煉為一個通用的單例提供者,實現「寫一次,處處復用」。
public sealed class Singleton
{
Singleton() { }
public static Singleton Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator() { } // 明確靜態建構函式,阻止 beforefieldinit
internal static readonly Singleton instance = new Singleton();
}
}
利用泛型型別參數 T 替換具體類別,並加上 where T : new() 約束,確保型別擁有公用無參數建構函式:
public class SingletonProvider<T> where T : new()
{
SingletonProvider() { }
public static T Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T instance = new T();
}
}
public class TestClass
{
private string _createdTimestamp;
public TestClass()
{
_createdTimestamp = DateTime.Now.ToString();
}
public void Write()
{
Debug.WriteLine(_createdTimestamp);
}
}
// 使用方式
SingletonProvider<TestClass>.Instance.Write();
Instance 時才建立實例。TestClass 本身無單例相關程式碼,可隨時改為非單例使用。SingletonProvider<MyClass>.Instance。作者在雙處理器超執行緒環境下,以 100 條執行緒並發測試,所有執行緒返回相同時間戳記,證明執行緒安全性。
泛型不僅是容器的型別安全工具,更是橫切關注點(如單例、快取、工廠)封裝重用的利器。下次需要單例時,請直接 SingletonProvider<T> 走起!