对象的创建方式始终代表了软件工业的生产力方向代表了先进软件技术发展的方向也代表了广大程序开发者的集体智慧。以new的方式创建通过工厂方法利用IoC容器都以不同的方式实现了活生生实例成员的创生。而本文所关注的LazyT也是干这事儿的。不过简单说来LazyT要实现的就是按“需”创建而不是按时创建。我们往往有这样的情景一个关联对象的创建需要较大的开销为了避免在每次运行时创建这种家伙有一种聪明的办法叫做实现“懒对象”或者延迟加载。.NET 4.0之前实现懒对象的机制需要开发者自己来实现与管理例如你可以翻开老赵同志的较为理想的延迟代理的编写方式一文来了解其原理和场合。可喜的是在.NET 4.0中包含的另一个好玩的家伙System.LazyT。它的定义如下[Serializable] public class LazyT { public Lazy(); public Lazy(bool isThreadSafe); public Lazy(FuncT valueFactory); public Lazy(FuncT valueFactory, bool isThreadSafe); public bool IsValueCreated { get; } public T Value { get; } public override string ToString(); }注VS2010 Beta2对LazyT和VS2010 Beta1有较大差异因此本文仅以最新版本为标准并不保证最终.NET 4.0正式版的实际情况。假设我们有一个大块头public class Big { public int ID { get; set; } // Other resources }那么可以使用如下的方式来实现Big的延迟创建static void Main(string[] args) { LazyBig lazyBig new LazyBig(); }从LazyT的定义可知其Value属性就是我们包装在Lazy Wrapper中的真实Big对象那么当我们第一次访问lazyBig.Value时就回自动的创建Big实例。static void Main(string[] args) { LazyBig lazyBig new LazyBig(); 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 }上述创建方式将引发运行时异常提示包装对象没有无参的构造函数。那么这种情形下的延迟加载该如何应对呢其实LazyT的构造中还包括public Lazy(FuncT valueFactory);它正是用来应对这样的挑战static void Main(string[] args) { // LazyBig lazyBig new LazyBig(); LazyBig lazyBig new LazyBig(() new Big(100)); Console.WriteLine(lazyBig.Value.ID); }其实从public Lazy(FuncT valueFactory)的定义可知valueFactory可以返回任意的T实例那么任何复杂的构造函数对象工厂或者IoC容器方式都可以在此以轻松的方式兼容例如public class BigFactory { public static Big Build() { return new Big(100); } }可以应用LazyT和BigFactory实现Big的延迟加载static void Main(string[] args) { LazyBig lazyBig new LazyBig(() BigFactory.Build()); Console.WriteLine(lazyBig.Value.ID); }提供多线程环境支持。另外的构造器public Lazy(bool isThreadSafe); public Lazy(FuncT valueFactory, bool isThreadSafe);中isThreadSafe则应用于多线程环境下如果isThreadSafe为false那么延迟加载对象则一次只能创建于一个线程。关于LazyT的应用其实已经不是一个纯粹的语言问题还涉及了对设计的考量例如实现整个对象的延迟加载或者实现延迟属性考量线程安全等等。既然是点滴就不说教太多。因为.NET 4.0提供的关注度实在不少我们眼花缭乱了。
NET]第三十三回,深入.NET 4.0之,Lazy<T>点滴
发布时间:2026/7/6 3:51:03
对象的创建方式始终代表了软件工业的生产力方向代表了先进软件技术发展的方向也代表了广大程序开发者的集体智慧。以new的方式创建通过工厂方法利用IoC容器都以不同的方式实现了活生生实例成员的创生。而本文所关注的LazyT也是干这事儿的。不过简单说来LazyT要实现的就是按“需”创建而不是按时创建。我们往往有这样的情景一个关联对象的创建需要较大的开销为了避免在每次运行时创建这种家伙有一种聪明的办法叫做实现“懒对象”或者延迟加载。.NET 4.0之前实现懒对象的机制需要开发者自己来实现与管理例如你可以翻开老赵同志的较为理想的延迟代理的编写方式一文来了解其原理和场合。可喜的是在.NET 4.0中包含的另一个好玩的家伙System.LazyT。它的定义如下[Serializable] public class LazyT { public Lazy(); public Lazy(bool isThreadSafe); public Lazy(FuncT valueFactory); public Lazy(FuncT valueFactory, bool isThreadSafe); public bool IsValueCreated { get; } public T Value { get; } public override string ToString(); }注VS2010 Beta2对LazyT和VS2010 Beta1有较大差异因此本文仅以最新版本为标准并不保证最终.NET 4.0正式版的实际情况。假设我们有一个大块头public class Big { public int ID { get; set; } // Other resources }那么可以使用如下的方式来实现Big的延迟创建static void Main(string[] args) { LazyBig lazyBig new LazyBig(); }从LazyT的定义可知其Value属性就是我们包装在Lazy Wrapper中的真实Big对象那么当我们第一次访问lazyBig.Value时就回自动的创建Big实例。static void Main(string[] args) { LazyBig lazyBig new LazyBig(); 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 }上述创建方式将引发运行时异常提示包装对象没有无参的构造函数。那么这种情形下的延迟加载该如何应对呢其实LazyT的构造中还包括public Lazy(FuncT valueFactory);它正是用来应对这样的挑战static void Main(string[] args) { // LazyBig lazyBig new LazyBig(); LazyBig lazyBig new LazyBig(() new Big(100)); Console.WriteLine(lazyBig.Value.ID); }其实从public Lazy(FuncT valueFactory)的定义可知valueFactory可以返回任意的T实例那么任何复杂的构造函数对象工厂或者IoC容器方式都可以在此以轻松的方式兼容例如public class BigFactory { public static Big Build() { return new Big(100); } }可以应用LazyT和BigFactory实现Big的延迟加载static void Main(string[] args) { LazyBig lazyBig new LazyBig(() BigFactory.Build()); Console.WriteLine(lazyBig.Value.ID); }提供多线程环境支持。另外的构造器public Lazy(bool isThreadSafe); public Lazy(FuncT valueFactory, bool isThreadSafe);中isThreadSafe则应用于多线程环境下如果isThreadSafe为false那么延迟加载对象则一次只能创建于一个线程。关于LazyT的应用其实已经不是一个纯粹的语言问题还涉及了对设计的考量例如实现整个对象的延迟加载或者实现延迟属性考量线程安全等等。既然是点滴就不说教太多。因为.NET 4.0提供的关注度实在不少我们眼花缭乱了。