深入.NET Framework 4.0 關(guān)于Lazy的點(diǎn)滴
在微軟發(fā)布的.NET Framework 4.0的Beta 2版本中,其又給我們帶來(lái)了很多新東西,由于不知道正式版與之前的版本是否有過(guò)改進(jìn),我們只在這里來(lái)單純地談?wù)勗?a >.NET Framework 4.0中關(guān)于Lazy<T>的實(shí)現(xiàn)。
1.Lazy<T>概述
我們也許會(huì)遇到這樣一種情況,我們有一個(gè)大家伙(大對(duì)象)需要?jiǎng)?chuàng)建,那么這個(gè)對(duì)象的創(chuàng)建時(shí)需要較長(zhǎng)的時(shí)間,同時(shí)也需要在托管堆上分配較多的空間。那么在.NET Framework 4.0中提供了這樣一個(gè)很聰明的方式:Lazy<T>(我們可以稱之為懶對(duì)象)。當(dāng)然,在之前,很多人也曾對(duì)其進(jìn)行過(guò)自己的實(shí)現(xiàn),那么我們?cè)谶@里就可以把Lazy<T>的作用總結(jié)為一句話:按需延遲加載。
2.Lazy<T>的使用
了解了Lazy<T>的作用,讓我們就來(lái)看下Lazy<T>如何應(yīng)用:
- classProgram
- {
- staticvoidMain(string[]args)
- {
- Lazy<Large>lazyObject=newLazy<Large>();
- Console.WriteLine(lazyObject.IsValueCreated);
- lazyObject.Value.Test();
- Console.WriteLine(lazyObject.IsValueCreated);
- }
- }
- [Serializable]
- classLarge
- {
- publicLarge(){}
- publicvoidTest()
- {
- Console.WriteLine("Test");
- }
- }
這個(gè)例子很簡(jiǎn)單,也是Lazy<T>最基本,也是最常用的應(yīng)用方式。
3.實(shí)現(xiàn)自己的Lazy<T>
在.NET Framework 4.0之前,大對(duì)象就是存在的,那么對(duì)于一個(gè)大型系統(tǒng)而言,怎么樣對(duì)付一個(gè)大對(duì)象呢。在我看來(lái)有兩點(diǎn):延遲加載和即時(shí)清理。前者解決創(chuàng)建問(wèn)題,后者解決回收問(wèn)題,那么在來(lái)看Lazy<T>的.NET Framework實(shí)現(xiàn)之前,我們先來(lái)自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Lazy<T>吧。
- classMyLazy<T>whereT:new()
- {
- privateTvalue;
- privateboolisLoaded;
- publicMyLazy()
- {
- isLoaded=false;
- }
- publicTValue
- {
- get
- {
- if(!isLoaded)
- {
- value=newT();
- isLoaded=true;
- }
- returnvalue;
- }
- }
- }
這應(yīng)該是最簡(jiǎn)單版本的Lazy<T>了,沒(méi)有線程安全檢測(cè),其實(shí)什么都沒(méi)有,只有著訪問(wèn)時(shí)創(chuàng)建真實(shí)對(duì)象,可是對(duì)于我們一般的應(yīng)用來(lái)說(shuō)也許就已經(jīng)足夠了。 #p#
4.Lazy<T>的.NET Framework實(shí)現(xiàn)
原本還想解釋下代碼的,可是太多了,就寫(xiě)些主要吧,其實(shí).NET Framework和上面的實(shí)現(xiàn)大同小異,有兩點(diǎn)主要的不同:
A.引入了Boxed內(nèi)部類:
- [Serializable]
- privateclassBoxed
- {
- //Fields
- internalTm_value;
- //Methods
- [TargetedPatchingOptOut("PerformancecriticaltoinlinethistypeofmethodacrossNGenimageboundaries")]
- internalBoxed(Tvalue)
- {
- this.m_value=value;
- }
- }
該內(nèi)部類取代了我在上面實(shí)現(xiàn)中的泛型約束,使之更通用,但是我們也應(yīng)該注意到,如果T為結(jié)構(gòu)體,那么由于T很大,所以裝箱拆箱反而也許是個(gè)更耗費(fèi)效率的事情,因此,個(gè)人建議,對(duì)值類型慎用Lazy<T>。
B.線程安全的控制
在線程安全的控制選項(xiàng)中,.NET Framework為我們提供了這樣的枚舉選項(xiàng):
- publicenumLazyThreadSafetyMode
- {
- None,
- PublicationOnly,
- ExecutionAndPublication
- }
不做多余解釋,關(guān)于這三者的具體意思,MSDN中已經(jīng)說(shuō)的很清楚了,可參加這里,里面的代碼比較麻煩,就不多說(shuō)了。
5.完善的大對(duì)象解決方案
在Anytao文章的回復(fù)中提到了一點(diǎn)是:Lazy+WeakReference才是實(shí)現(xiàn)一個(gè)大對(duì)象的完整解決之道,一個(gè)按需加載,一個(gè)不定清理,加到一起才完美。
本文轉(zhuǎn)自飛林沙的博客,
原文地址:http://www.cnblogs.com/kym/archive/2010/02/21/1670226.html
【編輯推薦】