一、說明 本文中的代碼類,在生產中使用了很長的時間,曾應用於多個企業多個項目實踐中,其中也踩了不少坑,總結了一些適用的業務情景, 重要的事情說三遍: a.本代碼類不是萬能藥,不要在業務情景中濫用! b.本代碼類是有效的可用的經典的,但不要在業務情景中濫用!! c.本代碼類是經過實踐考驗的,可放心使用 ...
一、說明
本文中的代碼類,在生產中使用了很長的時間,曾應用於多個企業多個項目實踐中,其中也踩了不少坑,總結了一些適用的業務情景,
重要的事情說三遍:
a.本代碼類不是萬能藥,不要在業務情景中濫用!
b.本代碼類是有效的可用的經典的,但不要在業務情景中濫用!!
c.本代碼類是經過實踐考驗的,可放心使用,但不要在業務情景中濫用!!!
具體濫用後會踩中什麼坑呢?嘿嘿~~認真看下麵代碼結合自己業務應用,自己分析問題~~
二、代碼
廢話不多說,代碼如下:
1 /// <summary> 2 /// 惰性泛型單例 3 /// </summary> 4 public class LazyInstance<T> 5 where T : class,new() 6 { 7 private static Lazy<T> lazyObj = new Lazy<T>(() => new T()); 8 9 public static T Instance 10 { 11 get 12 { 13 return lazyObj.Value; 14 } 15 } 16 }LazyInstance.cs
三、.NET 內置類及代碼說明
查看MSDN文檔,Lazy<T> 類,https://msdn.microsoft.com/zh-cn/library/dd642331(v=vs.110).aspx :
1 // 2 // 摘要: 3 // 提供對延遲初始化的支持。 4 // 5 // 類型參數: 6 // T: 7 // 指定正在延遲初始化的對象的類型。 8 public class Lazy<T> 9 { }
1 // 2 // 摘要: 3 // 初始化 System.Lazy`1 類的新實例。發生延遲初始化時,使用指定的初始化函數。 4 // 5 // 參數: 6 // valueFactory: 7 // 在需要時被調用以產生延遲初始化值的委托。 8 // 9 // 異常: 10 // T:System.ArgumentNullException: 11 // valueFactory 為 null。 12 public Lazy(Func<T> valueFactory);
1 // 2 // 摘要: 3 // 獲取當前 System.Lazy`1 實例的延遲初始化值。 4 // 5 // 返回結果: 6 // 當前 System.Lazy`1 實例的延遲初始化值。 7 // 8 // 異常: 9 // T:System.MemberAccessException: 10 // System.Lazy`1 實例初始化為使用正在惰性初始化的類型的預設構造函數,並且缺少訪問該構造函數的許可權。 11 // 12 // T:System.MissingMemberException: 13 // System.Lazy`1 實例初始化為使用正在惰性初始化的類型的預設構造函數,並且該類型沒有無參數的公共構造函數。 14 // 15 // T:System.InvalidOperationException: 16 // 初始化函數嘗試訪問此實例上的 System.Lazy`1.Value。 17 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 18 public T Value { get; }
Lazy<T> 類,我們說完了,若果還不明白就自己搜索一下,接下來說一下使用此類怎麼構成了單例:
初始化時:
1 private static Lazy<T> lazyObj = new Lazy<T>(() => new T());
在使用某個實例類時,例如 class A ,總是使用 A.Instance,而該屬性總是返回Lazy<T>.Value:
1 public static T Instance 2 { 3 get 4 { 5 return lazyObj.Value; 6 } 7 }
註意,上面都是用static修飾的,典型的構造函數賦值靜態屬性,實例使用靜態屬性保存值,只不過巧妙的借用了.NET內置的Lazy<T> 類,
完成實現了經典的單例模式,同時省去了鎖,惰性等實現代碼,同時代碼超級穩定!
四、使用方式
定義一個類:
1 public class ClassA : LazyInstance<ClassA> 2 { 3 public string Test() 4 { 5 return "惰性泛型單例!"; 6 } 7 }
在方法中使用這個類:
1 public void Invoke() 2 { 3 var result = ClassA.Instance.Test(); 4 }
蒙
2016-09-30 23:11 周五
支付寶打賞: 微信打賞: