.NET泛型04,使用Lazy<T>实现延迟加载

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

对于一些"大对象"的创建,我们常常希望延迟加载,即在需要的时候再创建对象实例。现在Lazy<T>很好地支持了这一特点。主要包括:

没有Lazy<T>之前Lazy<T>实例延迟加载的本质

没有Lazy<T>之前

在没有Lazy<T>之前,我们通过如下方式实现延迟加载。

publicclassLazySinleton

{

PRivateLazySingleton()

{}

publicstaticLazySingleton Instance

{

get

{

returnLazy.data;

}

}

privateclassLazy

{

staticLazy()

{}

internalstaticreadonlyLazySingleton data =newLazySingleton();

}

}

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, "Courier New", courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp{ background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }以上

● 通过私有构造函数屏蔽了LazySingleton类通过构造函数创建的方式

● 私有嵌套类Lazy的data字段负责提供一个LazySingleton的实例

● 只能通过LazySingleton的属性Instance,才能拿到内部类Lazy.data所代表的实例

Lazy<T>实例

先看Lazy<T>的定义:

publicclassLazy<T>{publicLazy();publicLazy(boolisThreadSafe);publicLazy(Func<T>valueFactory);publicLazy(LazyThreadSafeMode mode);publicLazy(Func<T> valueFactory,boolisThreadSafe);publicLazy(Funct<T>valueFactory, LazyThreadSafetyMode mode);publicboolIsValueCreated{get;}publicT Value {get;}publicoverridestringToStirng();

}

通过Lazy<T>的构造函数重载创建对象,再通过体现延迟加载的Value属性来实现对象的创建,并获取对象实例。

publicclassSomeClass

{publicintID{get;set;}

}

Lazy<SomeClass> temp =newLazy<SomeClass>();

Console.WriteLine(temp.Value.ID);

以上,只适用于没有构造函数的情况,如果有构造函数如何处理呢?

--使用public Lazy(Func<T> valueFactory),通过委托创建对象

pubicclassSomeClass

{publicintID{get;set;}publicSomeClass(intid)

{this.ID =id;

}

}

Lazy<SomeClass> temp =newLazy<SomeClass>(() =>newBig(100));

Console.WriteLine(temp.Value.ID);

延迟加载的本质

创建自定义延迟加载类。

publicclassMyLazy<T>{privatevolatileobjectboxed;//volatile说明在多线程状况下,也可以修改该字段privateFunc<T> valueFactory;//委托,用来生产T对象实例staticMyLazy(){}publicMyLazy(){}publicMyLazy(Func<T>valueFactory)

{this.valueFactory =valueFactory;

}publicT Value

{get{

Boxed boxed=null;if(this.boxed !=null)

{

boxed=this.boxedasBoxed;if(boxed !=null)

{returnboxed.value;

}

}returnthis.Init();

}

}//初始化对象实例privateT Init()

{

Boxed boxed=null;if(this.boxed ==null)

{

boxed=this.CreateValue();this.boxed =boxed;

}returnboxed.value;

}//创建内部类实例privateBoxed CreateValue()

{//如果创建对象实例的委托valueFactory存在if(this.valueFactory !=null)

{//就通过委托生成对象实例returnnewBoxed(this.valueFactory());

}else{//否则,通过反射生成对象实例returnnewBoxed((T)Activator.CreateInstance(typeof(T)));

}

}//内部嵌套类,通过构造函数对其字段赋值privateclassBoxed

{internalT value;internalBoxed(T value)

{this.value =value;

}

}

}

自定义带构造函数的类。

publicclassBig

{publicintID {get;set; }publicBig(intid)

{this.ID =id;

}

}

自定义创建对象实例的工厂类。

publicclassBigFactory

{publicstaticBig Build()

{returnnewBig(10);

}

}

客户端调用。

classProgram

{staticvoidMain(string[] args)

{

MyLazy<Big> temp =newMyLazy<Big>(() =>BigFactory.Build());

Console.WriteLine(temp.Value.ID);

Console.ReadKey();

}

}

延迟加载的本质大致是:

● 由延迟加载类的内部嵌套类产生对象实例

● 再通过延迟加载类的某个属性来延迟获取对象实例,而对象实例是通过委托等方式创建的

参考资料:

《你必须知道的.NET(第2版)》,作者王涛。

".NET泛型"系列包括:

.NET泛型01,为什么需要泛型,泛型基本语法.NET泛型02,泛型的使用.NET泛型03,泛型类型的转换,协变和逆变.NET泛型04,使用Lazy<T>实现延迟加载

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航