懒人懒类懒方法 - System.Lazy<T>

简介:

 我这个技术博客被冷落了近1年之后,我觉得不能再这样下去,至少应该平均2周发一篇博文。坚持了两三篇博文之后,我觉得今天是应该写点什么了,却发现这段时间以来似乎没什么值得摆出来的,仔细回想了一遍,大概就只有Lazy<T>还有点意思,可以写写。


  Lazy<T>,正如其名,是为懒人设计的一个懒加载处理类。所谓懒加载,最简单的实现就是事先申明变量,但在实际使用的时候才创建对象实例。比如,通常会这么写一个懒加载的属性:


1
2
3
4
5
6
private  IList< string > names;
public  IList< string > {
     get  {
         return  names ?? (names ==  new  List< string >());
     }
}


  懒加载比较典型的例子就是实现Singleton模式了。简单的Singleton通常会这样写:


1
2
3
4
5
6
7
8
9
public  class  Singleton1
{
     private  static  Singleton1 instance;
     public  static  Singleton1 Default
     {
         get  return  instance ?? (instance =  new  Singleton1()); }
     }
     private  Singleton1() { }
}


  改写成Lazy<T>实现


1
2
3
4
5
6
7
8
9
public  class  Singleton2
{
     private  static  readonly  Lazy<Singleton2> lazyInstance
             new  Lazy<Singleton2>();
     public  static  Singleton2 Default
     {
         get  return  lazyInstance.Value; }
     }
}


  不过上面这个例子不是真正的单例,使用Lazy<T>的默认构造产生懒加载实例,需要T类型有公共的默认构造,否则在运行时会抛出 System.MissingMemberException。所以单例里其实应该用


1
Lazy<T>(Func<T>)


  所以再改写


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public  class  Singleton3
{
     private  static  readonly  Lazy<Singleton3> lazyInstance
             new  Lazy<Singleton3>(Create);
     public  static  Singleton3 Default
     {
         get  return  lazyInstance.Value; }
     }
     private  static  Singleton3 Create()
     {
         return  new  Singleton3();
     }
     private  Singleton3() { }
}


  这么看来,Lazy<T>实现的代码貌似更多,没能偷到懒……不过,如果要求线程安全的Singleton呢,一般会这么实现:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public  class  Singleton4
{
     private  static  Singleton4 instance;
     private  static  readonly  object  locker =  new  object ();
     public  static  Singleton4 Default
     {
         get
         {
             if  (instance ==  null )
             {
                 lock  (locker)
                 {
                     if  (instance ==  null )
                     {
                         instance =  new  Singleton4();
                     }
                 }
             }
             return  instance;
         }
     }
     private  Singleton4() { }
}


  这段代码,又是锁又是判断的,光“instance == null”就判断了两次,为什么?想不明白就Google,再搞不懂就看个没这么复杂的实现


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public  class  Singleton5
{
     private  static  readonly  Lazy<Singleton5> lazyInstance
             new  Lazy<Singleton5>(Create,  true );
     public  static  Singleton5 Default
     {
         get  return  lazyInstance.Value; }
     }
     private  static  Singleton5 Create()
     {
         return  new  Singleton5();
     }
     private  Singleton5() { }
}


  也就是说,从线程不安全到线程安全,只换了个Lazy<T>的构造方法,多加了一个布尔参数就解决了——简单方便。Lazy<T>提供了6个构造方法,它的文档已经写得很清楚,就不多说了。


  还要说明的一点是,懒加载当然不只是为了Singleton而设计的,就拿本文中的第一个例子来说,它有可能会有更复杂也更实际一点的实现(需要的时候再从数据库去获取数据):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class  Blabla
{
     private  readonly  Lazy<IList< string >> lazyNames;
     public  Blabla()
     {
         lazyNames =  new  Lazy<IList< string >>(GetNameList);
     }
     private  IList< string > GetNameList()
     {
         DataTable data = dbHelper.getUsers();
         List< string > names =  new  List< string >();
         foreach  (DataRow row  in  data.Rows)
         {
             names.Add(row[ "name" ].ToString());
         }
         return  names;
     }
     public  IList< string > Names
     {
         get  return  lazyNames.Value; }
     }
}


  本文转自边城__ 51CTO博客,原文链接:http://blog.51cto.com/jamesfancy/1365402,如需转载请自行联系原作者

相关文章
|
2月前
|
缓存 Java 数据库
懒得一起加载:@Lazy注解的秘密
懒得一起加载:@Lazy注解的秘密
39 0
|
4月前
|
SQL C# 数据安全/隐私保护
|
8月前
|
存储 算法 编译器
【C++技能树】再也不怕没有对象了 --初识类
我们先来看看C语言解决一个问题的过程。
44 0
|
Java Spring 容器
面试官:@Configuration 和 @Component 注解的区别?大部分人都会答错!
面试官:@Configuration 和 @Component 注解的区别?大部分人都会答错!
104 0
面试官:@Configuration 和 @Component 注解的区别?大部分人都会答错!
|
算法 Java
Java常用类(4)--System类
Java常用类(4)--System类
62 0
Java常用类(4)--System类
vbs学习,书籍,看书笔记(4.1) 类基本语法,类的事件
vbs学习,书籍,看书笔记(4.1) 类基本语法,类的事件
|
测试技术 API
还在手写 Builder 模式?试试 Lombok 中的 @Builder 用法,太强了。。
还在手写 Builder 模式?试试 Lombok 中的 @Builder 用法,太强了。。
270 0
|
存储 设计模式 Dubbo
掌握这9个小技巧,你也可以轻松玩转Java代理机制,赶紧来试试吧!
动态代理机制使用了反射,Spring 中的 AOP 由于使用了动态代理,所以也相当于使用了反射机制。那么,代理是什么?动态代理又是什么?动态代理中是如何使用反射的?
88 0
|
Ubuntu 计算机视觉 Python
摄像机标定--很懒的方法
百度上找半天各种标定的方法,然而复制代码下来各种报错,或者就是没讲清楚到底怎么操作。 后来我突然想到opencv自带的例程说不到也有标定的代码,很幸运在sample/python/下找到了calibrate.py这个程序。
|
JSON 数据安全/隐私保护 图形学
“别人用Unity写代码为啥这么快,这么强”,“因为用了工具类呀”
在开发中,我们会将调用次数比较多的函数单独提出来写到一个类中,比如字符串转16进制,给字符串加密这些都是比较常用的,就可以将这些常用的函数提取出来,放到工具类中,方便调用