C#单例模式

保证程序运行时只有一个实例,考点:静态构造函数、私有构造函数、锁、线程安全、延时创建对象、readonly/const区别

单例的优点:
1.保证了所有的对象访问的都是同一个实例
2.由于类是由自己类控制实例化的,所以有相应的伸缩性

单例的缺点:
1.额外的系统开销,因为每次使用类的实例的时候,都要检查实例是否存在,可以通过静态实例该解决。
2.无法销毁对象,单例模式的特性决定了只有他自己才能销毁对象实例,但是一般情况下我们都没做这个事情。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 namespace SingletonPatterns
  8 {
  9     class Program
 10     {
 11         static void Main(string[] args)
 12         {
 13         }
 14     }
 15 
 16     #region 单例模式版本---1
 17     /// <summary>
 18     /// 该版本主要存在的问题(线程安全问题)当2个请求同时访问时可能会出现2个实例尽管不会异常
 19     /// 不能保证运行过程中只有一个实例
 20     /// </summary>
 21     public sealed class Singleton1
 22     {
 23         private static Singleton1 _instance;
 24         private Singleton1() { }
 25 
 26         public static Singleton1 Instance
 27         {
 28             get
 29             {
 30                 if (_instance == null)
 31                     _instance = new Singleton1();
 32                 return _instance;
 33             }
 34         }
 35     }
 36     #endregion
 37 
 38     #region 单例模式版本---2
 39     /// <summary>
 40     /// 使用在静态私有字段上通过new的形式,来保证在该类第一次被调用的时候创建实例,是不错的方式
 41     /// 但有一点需要注意的是,C#其实并不保证实例创建的时机,因为C#规范只是在IL里标记该静态字段是BeforeFieldInit
 42     /// 也就是说静态字段可能在第一次被使用的时候创建,也可能你没使用了,它也帮你创建了,也就是周期更早
 43     /// 我们不能确定到底是什么创建的实例。
 44     /// </summary>
 45     public sealed class Singleton2
 46     {
 47         private static readonly Singleton2 _instance = new Singleton2();
 48 
 49         /// <summary>
 50         /// 私有构造函数,确保用户在外部不能实例化新的实例
 51         /// </summary>
 52         private Singleton2() { }
 53 
 54         public static Singleton2 Instance
 55         {
 56             get
 57             {
 58                 return _instance;
 59             }
 60         }
 61     }
 62     #endregion
 63 
 64     #region 单例模式版本---3
 65     /// <summary>
 66     /// 使用volatile来修饰,是个不错的注意,确保instance在被访问之前被赋值实例,一般情况都是用这种方式来实现单例。
 67     /// </summary>
 68     public sealed class Singleton3
 69     {
 70         private static volatile Singleton3 _instance = null;
 71 
 72         /// <summary>
 73         /// Lock对象 线程安全使用
 74         /// </summary>
 75         public static object syncObject = new object();
 76 
 77         private Singleton3() { }
 78 
 79         public static Singleton3 Instance
 80         {
 81             get
 82             {
 83                 if (_instance == null)
 84                 {
 85                     lock (syncObject)
 86                     {
 87                         if (_instance == null)
 88                             _instance = new Singleton3();
 89                     }
 90                 }
 91                 return _instance;
 92             }
 93         }
 94     }
 95     #endregion
 96 
 97     #region 单例模式版本---4
 98     /// <summary>
 99     /// 这种方式,其实是很不错的,因为他确实保证了是个延迟初始化的单例(通过加静态构造函数)
100     /// 但是该静态构造函数里没有东西哦,所以能有时候会引起误解,尤其是在code review或者代码优化的时候
101     /// 不熟悉的人可能直接帮你删除了这段代码,那就又回到了版本2了哦,所以还是需要注意的
102     /// 不过如果你在这个时机正好有代码需要执行的话,那也不错。
103     /// </summary>
104     public class Singleton4
105     {
106         /// <summary>
107         /// 因为下面声明了静态构造函数,所以在第一次访问该类之前,new Singleton()语句不会执行
108         /// </summary>
109         private static readonly Singleton4 _instance = new Singleton4();
110 
111         public static Singleton4 Instance
112         {
113             get { return _instance; }
114         }
115 
116         private Singleton4() { }
117 
118         /// <summary>
119         /// 声明静态构造函数就是为了删除IL里的BeforeFieldInit标记,以去静态自动在使用之前被初始化
120         /// </summary>
121         static Singleton4() { }
122     }
123     #endregion
124 
125     #region 单例模式版本---5
126 
127     #endregion
128 
129     #region 单例模式版本---6
130 
131     #endregion
132 
133 
134 }
View Code

 

posted @ 2015-11-25 15:33  X.J.Tang  阅读(193)  评论(0编辑  收藏  举报