[你必須知道的.NET]第三十三回,深入.NET 4.0之,Lazy點滴

來源:互聯網
上載者:User
文章目錄
  • 參考文獻

anytao.net | 《你必須知道的.NET》網站 | Anytao技術部落格 

發布日期:2009.10.29 作者:Anytao
2009 Anytao.com ,Anytao原創作品,轉貼請註明作者和出處。

 

對象的建立方式,始終代表了軟體工業的生產力方向,代表了先進軟體技術發展的方向,也代表了廣大程式開發人員的集體智慧。以new的方式建立,通過Factory 方法,利用IoC容器,都以不同的方式實現了活生生執行個體成員的創生。而本文所關注的Lazy<T>也是幹這事兒的。不過,簡單說來,Lazy<T>要實現的就是按“需”建立,而不是按時建立。

我們往往有這樣的情景,一個關聯對象的建立需要較大的開銷,為了避免在每次運行時建立這種傢伙,有一種聰明的辦法叫做實現“懶對象”,或者消極式載入。.NET 4.0之前,實現懶對象的機制,需要開發人員自己來實現與管理,例如,你可以翻開老趙同志的較為理想的延遲代理的編寫方式一文來瞭解其原理和場合。可喜的是,在.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的延遲建立:

static void Main(string[] args){    Lazy<Big> lazyBig = new Lazy<Big>();}

從Lazy<T>的定義可知,其Value屬性就是我們封裝在Lazy Wrapper中的真實Big對象,那麼當我們第一次訪問lazyBig.Value時,就回自動的建立Big執行個體。

static void Main(string[] args){    Lazy<Big> lazyBig = new Lazy<Big>();    Console.WriteLine(lazyBig.Value.ID);}

當然,有其定義可知,Lazy遠沒有這麼小兒科,它同時還可以為我們提供以下的服務:

  • 通過IsValueCreated,擷取是否“已經”建立了執行個體對象。
  • 解決非預設建構函式問題。

顯而易見。我們的Big類並沒有提供帶參數建構函式,那麼如下的Big類:

public class Big{    public Big(int id)    {        this.ID = id;    }    public int ID { get; set; }    // Other resources}

上述建立方式將引發運行時異常,提示封裝對象沒有無參的建構函式。那麼,這種情形下的消極式載入,該如何應對呢?其實Lazy<T>的構造中還包括:

public Lazy(Func<T> valueFactory);

它正是用來應對這樣的挑戰:

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);}
  • 提供多線程環境支援。

另外的構造器:

public Lazy(bool isThreadSafe);public Lazy(Func<T> valueFactory, bool isThreadSafe);

中,isThreadSafe則應用於多線程環境下,如果isThreadSafe為false,那麼消極式載入對象則一次只能建立於一個線程。

 

關於Lazy<T>的應用,其實已經不是一個純粹的語言問題,還涉及了對設計的考量,例如實現整個對象的消極式載入,或者實現延遲屬性,考量安全執行緒等等。既然是點滴,就不說教太多。因為,.NET 4.0提供的關注度實在不少,我們眼花繚亂了。

 

參考文獻
  • Lazy Initialization, http://msdn.microsoft.com/en-us/library/dd997286(VS.100).aspx  

 

更多閑言碎語,關注anytao.net

 

anytao | 2009 Anytao.com

2009/10/29 | http://anytao.cnblogs.com/ | http://www.anytao.net/blog/post/2009/10/28/anytao-insidenet-33-about-lazy.aspx

本文以“現狀”提供且沒有任何擔保,同時也沒有授予任何權利。 | This posting is provided "AS IS" with no warranties, and confers no rights.

本文著作權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.