C#基础知识回顾---你不知道的Lazy<T>
对象的创建方式,始终代表了软件工业的生产力方向,代表了先进软件技术发展的方向,也代表了广大程序开发者的集体智慧。以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提供的关注度实在不少,我们眼花缭乱了。
郑重声明本文非原创……
C#基础知识回顾---你不知道的Lazy<T>的更多相关文章
- java基础知识回顾之---java String final类普通方法
		
辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /* * 按照面向对象的思想对字符串进行功能分类. * ...
 - C#基础知识回顾-- 反射(3)
		
C#基础知识回顾-- 反射(3) 获取Type对象的构造函数: 前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”, 其他没有什么可以写的了,前两篇主要是铺垫, ...
 - C#基础知识回顾-- 反射(1)
		
C#基础知识回顾-- 反射(1) 反射(reflection)是一种允许用户获得类型信息的C#特性.术语“反射”源自于它的工作方式: Type对象映射它所代表的底层对象.对Type对象进行查询可以 ...
 - C#基础知识回顾--线程传参
		
C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...
 - python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器      同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。
		
本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...
 - Java基础知识回顾之七 ----- 总结篇
		
前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...
 - C++ 基础知识回顾总结
		
一.前言 为啥要写这篇博客?答:之前学习的C和C++相关的知识,早就被自己忘到一边去了.但是,随着音视频的学习的不断深入,和C/C++打交道的次数越来越多,看代码是没问题的,但是真到自己操刀去写一些代 ...
 - scrapy实战1,基础知识回顾和虚拟环境准备
		
视频地址 https://coding.imooc.com/learn/list/92.html 一. 基础知识回顾 1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...
 - C#学习笔记(基础知识回顾)之值类型与引用类型转换(装箱和拆箱)
		
一:值类型和引用类型的含义参考前一篇文章 C#学习笔记(基础知识回顾)之值类型和引用类型 1.1,C#数据类型分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型.如果int只不过是栈上的一个4字 ...
 
随机推荐
- 深度学习主机环境配置: Ubuntu16.04+GeForce GTX 1080+TensorFlow
			
接上文<深度学习主机环境配置: Ubuntu16.04+Nvidia GTX 1080+CUDA8.0>,我们继续来安装 TensorFlow,使其支持GeForce GTX 1080显卡 ...
 - Linux安全之SYN攻击原理及其应对措施
			
TCP自从1974年被发明出来之后,历经30多年发展,目前成为最重要的互联网基础协议,但TCP协议中也存在一些缺陷. SYN攻击就是利用TCP协议的缺陷,来导致系统服务停止正常的响应. SYN攻击原理 ...
 - CentOS 7配置Let’s Encrypt支持免费泛域名证书
			
Let’s Encrypt从2018年开始支持泛域名证书,有效期3个月,目前仅支持acme方式申请,暂不支持certbot. 1.安装acme.sh curl https://get.acme.sh ...
 - 检查.net dll构建的目标平台是any cpu、x86、x64
			
有时候,需要检查构建的dll是否针对正确的平台 可以使用CorFlags.exe(它是.NET Framework SDK的一部分)从dll中查找此信息.运行CorFlags.exe将产生以下输出: ...
 - [翻译]第三天- 在 Mac 上运行 .NET Core 应用程序
			
原文: http://michaelcrump.net/part3-aspnetcore/ *** 简介 该系列文章的完整列表如下: 第一天 - 在 Windows 下安装和运行 .NET Core ...
 - Aspose Word.Dll库自带的bug导致The document appears to be corrupted and cannot be loaded 问题处理。
			
问题的详细描述: C#在开发过程中使用Aspose.word.dll库去实现word套打功能.但是,最近客户反映出现了一个问题,在打印文档的时候,系统报错.经过定位分析发现是Aspose.word.d ...
 - WPF TreeView IsExpanded 绑定不上的问题
			
最近项目上需要通过MVVM来控制TreeView,其中需要需要控制通过搜索来定位某个节点,正常逻辑下,首先通过需要在树上面找到该节点,然后选中该节点,并将该节点的父节点展开,这个时候需要通过MVVM来 ...
 - Deque(队列)
			
目录 Deque 概述 特点 常用方法 双向队列操作 ArrayDeque Deque 概述 一个线性 collection,支持在两端插入和移除元素.名称 deque 是"double e ...
 - java打包jar后,使之一直在linux上运行,不随终端退出而关闭
			
nohup java -jar xxx.jar&
 - linux的RPM软件包管理工具
			
RPM(Redhat Package Manage)原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序,由于它遵循GPL规则且功能强大方便,因而广受欢迎.逐渐受到其他发行版的采 ...