[你必须知道的.NET]第三十三回,深入.NET 4.0之,LazyT点滴
對象的創(chuàng)建方式,始終代表了軟件工業(yè)的生產力方向,代表了先進軟件技術發(fā)展的方向,也代表了廣大程序開發(fā)者的集體智慧。以new的方式創(chuàng)建,通過工廠方法,利用IoC容器,都以不同的方式實現了活生生實例成員的創(chuàng)生。而本文所關注的Lazy<T>也是干這事兒的。不過,簡單說來,Lazy<T>要實現的就是按“需”創(chuàng)建,而不是按時創(chuàng)建。
我們往往有這樣的情景,一個關聯(lián)對象的創(chuàng)建需要較大的開銷,為了避免在每次運行時創(chuàng)建這種家伙,有一種聰明的辦法叫做實現“懶對象”,或者延遲加載。.NET 4.0之前,實現懶對象的機制,需要開發(fā)者自己來實現與管理,例如,你可以翻開老趙同志的較為理想的延遲代理的編寫方式一文來了解其原理和場合。可喜的是,在.NET 4.0中包含的另一個好玩的家伙System.Lazy<T>。它的定義如下:
[Serializable] public class Lazy<T> {public Lazy();public Lazy(bool isThreadSafe);public Lazy(Func<T> valueFactory);public Lazy(Func<T> valueFactory, bool isThreadSafe);public bool IsValueCreated { get; }public T Value { get; }public override string ToString(); } 注:VS2010 Beta2對Lazy<T>和VS2010 Beta1有較大差異,因此本文僅以最新版本為標準,并不保證最終.NET 4.0正式版的實際情況。假設,我們有一個大塊頭:
public class Big {public int ID { get; set; }// Other resources }那么,可以使用如下的方式來實現Big的延遲創(chuàng)建:
static void Main(string[] args) {Lazy<Big> lazyBig = new Lazy<Big>(); }從Lazy<T>的定義可知,其Value屬性就是我們包裝在Lazy Wrapper中的真實Big對象,那么當我們第一次訪問lazyBig.Value時,就回自動的創(chuàng)建Big實例。
static void Main(string[] args) {Lazy<Big> lazyBig = new Lazy<Big>();Console.WriteLine(lazyBig.Value.ID); }當然,有其定義可知,Lazy遠沒有這么小兒科,它同時還可以為我們提供以下的服務:
- 通過IsValueCreated,獲取是否“已經”創(chuàng)建了實例對象。
- 解決非默認構造函數問題。
顯而易見。我們的Big類并沒有提供帶參數構造函數,那么如下的Big類:
public class Big {public Big(int id){this.ID = id;}public int ID { get; set; }// Other resources }上述創(chuàng)建方式將引發(fā)運行時異常,提示包裝對象沒有無參的構造函數。那么,這種情形下的延遲加載,該如何應對呢?其實Lazy<T>的構造中還包括:
public Lazy(Func<T> valueFactory);它正是用來應對這樣的挑戰(zhàn):
static void Main(string[] args) {// Lazy<Big> lazyBig = new Lazy<Big>();Lazy<Big> lazyBig = new Lazy<Big>(() => new Big(100));Console.WriteLine(lazyBig.Value.ID); }其實,從public Lazy(Func<T> valueFactory)的定義可知,valueFactory可以返回任意的T實例,那么任何復雜的構造函數,對象工廠或者IoC容器方式都可以在此以輕松的方式兼容,例如:
public class BigFactory {public static Big Build(){return new Big(100);} }可以應用Lazy<T>和BigFactory實現Big的延遲加載:
static void Main(string[] args) {Lazy<Big> lazyBig = new Lazy<Big>(() => BigFactory.Build());Console.WriteLine(lazyBig.Value.ID); }- 提供多線程環(huán)境支持。
另外的構造器:
public Lazy(bool isThreadSafe); public Lazy(Func<T> valueFactory, bool isThreadSafe);中,isThreadSafe則應用于多線程環(huán)境下,如果isThreadSafe為false,那么延遲加載對象則一次只能創(chuàng)建于一個線程。
?
關于Lazy<T>的應用,其實已經不是一個純粹的語言問題,還涉及了對設計的考量,例如實現整個對象的延遲加載,或者實現延遲屬性,考量線程安全等等。既然是點滴,就不說教太多。因為,.NET 4.0提供的關注度實在不少,我們眼花繚亂了。
?
參考文獻
- Lazy Initialization,?http://msdn.microsoft.com/en-us/library/dd997286(VS.100).aspx??
總結
以上是生活随笔為你收集整理的[你必须知道的.NET]第三十三回,深入.NET 4.0之,LazyT点滴的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 管理全局包、缓存和临时文件夹
- 下一篇: 哪些渠道可以办理民生白条联名卡