昨天我们说了一个.Net 4.0里面StringBuilder新增的Clear()方法及其实现,非常简单.今天要说的就稍微复杂一点了.
语言和模式互相促进,语言让模式实现有更多可能性,越来越多优秀的被语言实现.模式实现的责任从开发者转移到语言.延迟初始化(Lazyinitialization)已经在.Net 4.0中给出了默认实现.本文将探究其使用方法和实现.
为什么要延迟初始化(Lazy initialization)?
平时开发能接触到延迟初始化可能是在两个地方,一个是单件模式Singletonpattern,一个是Nhibernate;这两个典型场景很能说明为什么需要延迟初始化:
1.需要初始化的对象属于昂贵的资源,直到使用的时候再初始化load-on-demand
2.初始化过程本身相当复杂,代码中要避免这种无谓复杂性,直到使用再初始化
更多延迟初始化的资料,请点击这里;
.Net 4.0 Lazy<T>实现Lazy initialization
.Net 4.0中的延迟初始化的默认实现时Lazy<T>,我们通过一个简单的例子看一下怎么使用,为了方便讨论我们新建一个Student的实体类:
public class Student
{
public int ID
{
get ; set ;
}
public string Name
{
get ; set ;
}
}
延迟初始化Student:
Lazy < Student > student = newLazy < Student > ();
Console.WriteLine(student);
student.Value.ID = 23 ;
student.Value.Name = " New " ;
Console.WriteLine(student);
我们在Console.WriteLine(student); 一行设置断点查看,发现IsValueCreated是false ,Value值是null,截图如下:
继续往下走,在student.Value.ID = 23;赋值的时候,再次查看student对象的值,IsValueCreated为true,Value已经不为空,见下图.
我们可以猜想,应该是在Value的Get方法中对对象进行了实例化,打开Reflector v6验证:
是不是和我们想的一样呢?
为了更清晰的看出延迟加载的处理逻辑,我按照这个代码的实现思路,去掉复杂应用场景中队异常,多线程等方面的代码,重新实现了一个Lazy<T>,就叫它YaLazy<T>吧
1 public class YaLazy < T >
2 {
3 private bool _isValueCreated = false ;
4 public bool IsValueCreated
5 {
6 get
7 {
8 return _isValueCreated;
9 }
10 }
11 private T _value;
12 public T Value
13 {
14 get
15 {
16 if ( this ._value != null )
17 {
18 return (T)_value;
19 }
20 return CreateValue();
21
22 }
23 }
24 private T CreateValue()
25 {
26 _isValueCreated = true ;
27 _value = (T)Activator.CreateInstance( typeof (T));
28 return _value;
29 }
30 }
使用方法和Lazy<T>类似:
1 YaLazy < Student > student2 = new YaLazy < Student > ();
2 Console.WriteLine(student2);
3 student2.Value.ID = 23 ;
4 student2.Value.Name = " New " ;
5 Console.WriteLine(student2);
6
建议单步调试~