博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET泛型04,使用Lazy<T>实现延迟加载
阅读量:7025 次
发布时间:2019-06-28

本文共 3729 字,大约阅读时间需要 12 分钟。

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

 

 

  没有Lazy<T>之前

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

public class LazySinleton
{
private LazySingleton()
{}
 
public static LazySingleton Instance
{
get
{
return Lazy.data;
}
}
 
private class Lazy
{
static Lazy()
{}
 
internal static readonly LazySingleton data = new LazySingleton();
}
}
 

以上

● 通过私有构造函数屏蔽了LazySingleton类通过构造函数创建的方式
● 私有嵌套类Lazy的data字段负责提供一个LazySingleton的实例
● 只能通过LazySingleton的属性Instance,才能拿到内部类Lazy.data所代表的实例

 

  Lazy<T>实例

先看Lazy<T>的定义:

public class Lazy
{ public Lazy(); public Lazy(bool isThreadSafe); public Lazy(Func
valueFactory); public Lazy(LazyThreadSafeMode mode); public Lazy(Func
valueFactory, bool isThreadSafe); public Lazy(Funct
valueFactory, LazyThreadSafetyMode mode); public bool IsValueCreated{
get;} public T Value {
get;} public override string ToStirng();}

 

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

public class SomeClass{    public int ID{
get;set;}}Lazy
temp = new Lazy
();Console.WriteLine(temp.Value.ID);

 

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

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

pubic class SomeClass{    public int ID{
get;set;} public SomeClass(int id) { this.ID = id; }}Lazy
temp = new Lazy
(() => new Big(100));Console.WriteLine(temp.Value.ID);

 

  延迟加载的本质

创建自定义延迟加载类。

public class MyLazy
{ private volatile object boxed; //volatile说明在多线程状况下,也可以修改该字段 private Func
valueFactory; //委托,用来生产T对象实例 static MyLazy(){} public MyLazy(){} public MyLazy(Func
valueFactory) { this.valueFactory = valueFactory; } public T Value { get { Boxed boxed = null; if (this.boxed != null) { boxed = this.boxed as Boxed; if (boxed != null) { return boxed.value; } } return this.Init(); } } //初始化对象实例 private T Init() { Boxed boxed = null; if (this.boxed == null) { boxed = this.CreateValue(); this.boxed = boxed; } return boxed.value; } //创建内部类实例 private Boxed CreateValue() { //如果创建对象实例的委托valueFactory存在 if (this.valueFactory != null) { //就通过委托生成对象实例 return new Boxed(this.valueFactory()); } else { //否则,通过反射生成对象实例 return new Boxed((T)Activator.CreateInstance(typeof(T))); } } //内部嵌套类,通过构造函数对其字段赋值 private class Boxed { internal T value; internal Boxed(T value) { this.value = value; } } }

 

自定义带构造函数的类。

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

 

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

public class BigFactory    {        public static Big Build()        {            return new Big(10);        }    }

客户端调用。

class Program    {        static void Main(string[] args)        {            MyLazy temp = new MyLazy(() => BigFactory.Build());            Console.WriteLine(temp.Value.ID);            Console.ReadKey();        }    }

 

延迟加载的本质大致是:

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

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

 

参考资料:

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

 

".NET泛型"系列包括:

转载地址:http://mloxl.baihongyu.com/

你可能感兴趣的文章
jQuery方法position()与offset()区别
查看>>
Flume特点
查看>>
队列 句子分析 精辟的诠释 有图片
查看>>
在switch的default代码块中增加AssertionError错误
查看>>
JS:1.3,函数(function)
查看>>
Ubuntu下升级Git以及获取ssh keys的代码
查看>>
在C#代码中应用Log4Net(一)简单使用Log4Net
查看>>
webservice 测试窗体只能用于来自本地计算机的请求
查看>>
14.9. 桌面支持
查看>>
部署Linux下的man慢查询中文帮助手册环境
查看>>
在VM重启之后,重新打开HANAStudio总是报用户名错误的解决方法
查看>>
算法分析实验题集
查看>>
让WordPress主题支持语言本地化(使用poedit软件实现中文翻译功能)
查看>>
[WinAPI] API 6 [操作驱动器挂载点]
查看>>
SQL 在查询中插入行号--自定义分页的另外一种实现方式
查看>>
另类Unity热更新大法:代码注入式补丁热更新
查看>>
(cljs/run-at (JSVM. :browser) "搭建刚好可用的开发环境!")
查看>>
有时我们需要调用一个函数时,返回多个不同类型的数据
查看>>
IdentityServer4 通过 AccessToken 获取 UserClaims
查看>>
HIVE json格式数据的处理
查看>>