对象的创建方式,始终代表了软件工业的生产力方向,代表了先进软件技术发展的方向,也代表了广大程序开发者的集体智慧。以new的方式创建,通过工厂方法,利用IoC容器,都以不同的方式实现了活生生实例成员的创生。而本文所关注的Lazy<T>也是干这事儿的。不过,简单说来,Lazy<T>要实现的就是按“需”创建,而不是按时创建。
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
}
static void Main(string[] args)
{
Lazy<Big> lazyBig = new Lazy<Big>();
Console.WriteLine(lazyBig.Value.ID);
}
从Lazy<T>的定义可知,其Value属性就是我们包装在Lazy Wrapper中的真实Big对象,那么当我们第一次访问lazyBig.Value时,就回自动的创建Big实例。
当然,有其定义可知,Lazy远没有这么小儿科,它同时还可以为我们提供以下的服务:
- 通过IsValueCreated,获取是否“已经”创建了实例对象。
- 解决非默认构造函数问题。
显而易见。我们的Big类并没有提供带参数构造函数,那么如下的Big类:
public class Big { public Big(int id) { this.ID = id; } public int ID { get; set; } // Other resources }
解决的方法 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提供的关注度实在不少,我们眼花缭乱了。
转载自 https://www.cnblogs.com/smiler/p/3264968.html