欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#中单例模式的几种实现方式

程序员文章站 2022-03-07 17:04:37
...

       单例模式中,实现方式有以下几种,自己简单地总结了一下。其中,通过一次判空(只适用于单线程环境)和一次判空加锁(多线程,但效率不高),这两种方法就不多说了,下面只陈述改良之后的方法:

方法一:通过加锁,两次判空实现单例模式
 public sealed class SingleTon1
     //由sealed修饰的类或方法将不能被继承或是重写。   
   {
       private SingleTon1() { }
       private static readonly object MyLock = new object();
       private static SingleTon1 instance = null;
       public static SingleTon1 GetInstance()
       {
           //第一次判断省去加锁的过程消耗
           if (instance == null)
           {
               //多线程中保证只有一个线程能够创建实例
               lock (MyLock)
               {
                   //加锁过程也是多线程,所以需要再次判断
                   if (instance == null)
                   {
                       instance = new SingleTon1();
                   }
               }
           }
           return instance;
       }
   }
方法二:借助C#独有的特性,利用静态变量实现单例模式
   public sealed class SingleTon2
   {
       private SingleTon2() { }
       private static readonly SingleTon2 Instance = new SingleTon2();
       public static SingleTon2 GetInstance()
       {
           return Instance;
       }
   }
方法三:利用静态构造函数实现,与方法二同理
 public sealed class SingleTon3
  {
      private SingleTon3() { }
      private static readonly SingleTon3 Instance = null;
      static SingleTon3()
      {
          Instance = new SingleTon3();
      }
      public static SingleTon3 GetInstance()
      {
          return Instance;
      }    
  }

 
       静态构造函数只执行一次,在静态构造函数中初始化静态变量,这样就保证了只初始化一次实例。但是,只要第一次用到Singleton3的时候就会执行静态构造函数,如果不需要创建实例,就会白白浪费资源,于是,下面的方法

方法四:按需创建实例
  public sealed class SingleTon4
    {
        private SingleTon4() { }
        public static SingleTon4 GetInstance()
        {
            return Nested.Instance;
        }
        //创建一个嵌套类
        class Nested
        {
            internal static readonly SingleTon4 Instance = null;
            static Nested()
            {
                Instance = new SingleTon4();
            }
        }
    }

 
       类型Nested只有在调用SingleTon4 GetInstance()的时候才用到,由于其私有属性,他人无法使用Nested类型。因此,当我们第一次通过GetInstance()得到SingleTon4的实例时,会自动调用Nested的静态构造函数来创建实例Instance;如果我们不调用方法GetInstance()就不会触发.NET运行时调用Nested,也就不会创建实例,真正实现了按需创建。