C#基礎知識回顧---你不知道的Lazy


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

我們往往有這樣的情景,一個關聯對象的創建需要較大的開銷,為了避免在每次運行時創建這種家伙,有一種聰明的辦法叫做實現“懶對象”,或者延遲加載。.NET 4.0之前,實現懶對象的機制,需要開發者自己來實現與管理它的定義如下:

 

[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(); }

假設,我們有一個大塊頭:

public class Big { public int ID { get; set; } // Other resources
}

從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提供的關注度實在不少,我們眼花繚亂了。

 鄭重聲明本文非原創……

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM