C# 創建單例的多種方式
關於為什麼需要創建單例?這裡不過多介紹,具體百度知。
關於C# 創建單例步驟或條件吧
1、聲明靜態變量;
2、私有構造函數(無法實例化)
3、靜態創建實例的方法;至於我這裡的Singleton是sealed ,隻是為瞭防止被繼承,其實有私有構造函數足夠瞭,這裡隻是為瞭代碼可讀性。
第一種常見的方式創建單例:
/// <summary> /// 不安全的單例 /// </summary> public sealed class Singleton { private static Singleton _Singleton; private Singleton() { } public static Singleton GetSingleton() { if (_Singleton == null) { _Singleton = new Singleton(); } return _Singleton; } }
註:為什麼說是不安全的單例,多線程訪問時可能會new多個對象…
第二種方式創建單例:
/// <summary> /// (多線程)安全單例 /// </summary> public sealed class Singleton { private static Singleton _Singleton; private static readonly object obj = new object(); private Singleton() { } public static Singleton GetSingleton() { if (_Singleton == null) { //加鎖保護,在多線程下可以確保實例值被創建一次。缺點是每 次獲取單例,都要進行判斷,涉及到的鎖和解鎖比較耗資源。 lock (obj) { if (_Singleton == null) { _Singleton = new Singleton(); } } } return _Singleton; } }
註:為瞭解決上面第一種方式創建的不安全實例問題應用而生。
第三種方式創建單例:
/// <summary> /// 隻讀單例 /// </summary> public sealed class Singleton { private static readonly Singleton instance = new Singleton(); private Singleton() { } public static Singleton Instance { get { return instance; } } }
/// <summary> /// 基於上面的隻讀單例=自動屬性隻讀單例(語法糖) /// </summary> public sealed class Singleton { private Singleton() { } public static Singleton Instance { get; } = new Singleton(); }
註:隻讀屬性式=>借助readonly屬性,instance隻被初始化一次,同樣達到瞭單例的效果。在引用函數執行第一句話之前,instance其實已經被賦值瞭,並不是預期的 隻有到訪問Instance變量時才創建對象。
第四種方式創建單例:
/// <summary> /// Singleton中加上靜態構造函數。 /// </summary> public sealed class Singleton { public static readonly Singleton instance = new Singleton(); private Singleton() { Console.WriteLine("初始化1!"); } static Singleton() { } public static Singleton Instance { get { return instance; } } }
註:為瞭解決(第三種隻讀屬性實例)在執行第一句代碼之前,實例已經被初始化問題。
第五種方式創建單例:
/// <summary> /// 使用Lazy創建單例,默認是線程安全的 /// </summary> public sealed class Singleton { private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());// private Singleton() { } public static Singleton Instance { get { return instance.Value; } } }
// 貼一下關於上面Lazy<T> s=new Lazy<T>()參數的定義; // 摘要: // 初始化System.Lazy`1類的新實例。 懶惰初始化時 // 發生時,使用指定的初始化函數和初始化模式。 // 參數: // valueFactory: // 被調用以生成延遲初始化值的委托是必需的參數 // // isThreadSafe: // 如果要使此實例可由多個線程同時使用,則為true; false //使此實例一次隻能由一個線程使用。 public Lazy(Func<T> valueFactory, bool isThreadSafe);
以上就是C# 創建單例的多種方式的詳細內容,更多關於c# 創建單例的資料請關註WalkonNet其它相關文章!