在微软发布的.NET Framework 4.0的Beta 2版本中,其又给我们带来了很多新东西,由于不知道正式版与之前的版本是否有过改进,我们只在这里来单纯地谈谈在.NET Framework 4.0中关于Lazy<T>的实现。
1.Lazy<T>概述
我们也许会遇到这样一种情况,我们有一个大家伙(大对象)需要创建,那么这个对象的创建时需要较长的时间,同时也需要在托管堆上分配较多的空间。那么在.NET Framework 4.0中提供了这样一个很聪明的方式:Lazy<T>(我们可以称之为懒对象)。当然,在之前,很多人也曾对其进行过自己的实现,那么我们在这里就可以把Lazy<T>的作用总结为一句话:按需延迟加载。
2.Lazy<T>的使用
了解了Lazy<T>的作用,让我们就来看下Lazy<T>如何应用:
- 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");
- }
- }
这个例子很简单,也是Lazy<T>最基本,也是最常用的应用方式。
3.实现自己的Lazy<T>
在.NET Framework 4.0之前,大对象就是存在的,那么对于一个大型系统而言,怎么样对付一个大对象呢。在我看来有两点:延迟加载和即时清理。前者解决创建问题,后者解决回收问题,那么在来看Lazy<T>的.NET Framework实现之前,我们先来自己实现一个简单的Lazy<T>吧。
- classMyLazy<T>whereT:new()
- {
- privateTvalue;
- privateboolisLoaded;
- publicMyLazy()
- {
- isLoaded=false;
- }
- publicTValue
- {
- get
- {
- if(!isLoaded)
- {
- value=newT();
- isLoaded=true;
- }
- returnvalue;
- }
- }
- }
这应该是最简单版本的Lazy<T>了,没有线程安全检测,其实什么都没有,只有着访问时创建真实对象,可是对于我们一般的应用来说也许就已经足够了。 #p#
4.Lazy<T>的.NET Framework实现
原本还想解释下代码的,可是太多了,就写些主要吧,其实.NET Framework和上面的实现大同小异,有两点主要的不同:
A.引入了Boxed内部类:
- [Serializable]
- privateclassBoxed
- {
- //Fields
- internalTm_value;
- //Methods
- [TargetedPatchingOptOut("PerformancecriticaltoinlinethistypeofmethodacrossNGenimageboundaries")]
- internalBoxed(Tvalue)
- {
- this.m_value=value;
- }
- }
该内部类取代了我在上面实现中的泛型约束,使之更通用,但是我们也应该注意到,如果T为结构体,那么由于T很大,所以装箱拆箱反而也许是个更耗费效率的事情,因此,个人建议,对值类型慎用Lazy<T>。
B.线程安全的控制
在线程安全的控制选项中,.NET Framework为我们提供了这样的枚举选项:
- publicenumLazyThreadSafetyMode
- {
- None,
- PublicationOnly,
- ExecutionAndPublication
- }
不做多余解释,关于这三者的具体意思,MSDN中已经说的很清楚了,可参加这里,里面的代码比较麻烦,就不多说了。
5.完善的大对象解决方案
在Anytao文章的回复中提到了一点是:Lazy+WeakReference才是实现一个大对象的完整解决之道,一个按需加载,一个不定清理,加到一起才完美。
本文转自飞林沙的博客,
原文地址:http://www.cnblogs.com/kym/archive/2010/02/21/1670226.html
【编辑推荐】