.net framework为我们提供了一个Lazy<T> 类型,给我们开发带来很多便利,看如下的代码,有这样一个Class做示例:


1:      public class Person
2:      {
3:          public int Age { get; set; }
4:
5:          public Person()
6:          {
7:              Age = 1;
8:              Console.WriteLine("Created");
9:          }
10:
11:          public void Action()
12:          {
13:              Console.WriteLine("Run");
14:          }
15:      }


接着我们看如何延迟加载加载它:


1:          [Test]
2:          public void TestLazyObject()
3:          {
4:              Lazy<Person> person = new Lazy<Person>(() => new Person() { Age=28 });
5:              var p = person.Value;
6:
7:              if (person.IsValueCreated)
8:                  Console.WriteLine("Person is initialized now..");
9:
10:              Assert.AreEqual(28, p.Age);
11:          }


注意上面的代码只有第5行被执行后,Person这个对象才被创建,输出:

Created Person is initialized now..
利用这个特性,我们可以实现Singleton模式,我们先定义这样的一个类型:


1:      /// <summary>
2:      /// Singleton under .net framework 4.0
3:      /// </summary>
4:      /// <typeparam name="T">specific class</typeparam>
5:      /// <seealso cref="http://msdn.microsoft.com/en-us/library/dd642331.aspx"/>
6:      /// <remarks>author Petter Liu </remarks>
7:      public static class Singleton<T> where T:class
8:      {
9:          // Initializes a new instance of the Lazy<T> class. When lazy initialization occurs, the specified
10:          //     initialization function and initialization mode are used.
11:          private static readonly Lazy<T> current = new Lazy<T>(
12:              () =>
13:                  Activator.CreateInstance<T>(),    // factory method
14:                  true);                                       // double locks
15:
16:          public static object Current
17:          {
18:              get { return current.Value; }
19:          }
20:      }


注意上面的代码第14行,指定线程安全,这就等于是double check, 我们还可以看下这个构造函数的定义:


public Lazy(Func<T> valueFactory, bool isThreadSafe) : this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
{
}


当第二个参数为true时选择是LazyThreadSafetyMode.ExecutionAndPublication。最后是UnitTest:


1:          [Test]
2:          public void TestUsingLayzImplementSingleton()
3:          {
4:             var person1 = Singleton<Person>.Current;
5:             var person2 = Singleton<Person>.Current;
6:
7:             Assert.AreEqual(person1, person2);
8:          }