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

C# 创建单例的多种方式

程序员文章站 2022-03-30 11:19:36
关于为什么需要创建单例?这里不过多介绍,具体百度知。 关于c# 创建单例步骤或条件吧1、声明静态变量;2、私有构造函数(无法实例化)3、静态创建实例的方法;至于我这里的singleton是sealed...

关于为什么需要创建单例?这里不过多介绍,具体百度知。

  关于c#  创建单例步骤或条件吧

1、声明静态变量;

2、私有构造函数(无法实例化)

3、静态创建实例的方法;至于我这里的singleton是sealed ,只是为了防止被继承,其实有私有构造函数足够了,这里只是为了代码可读性。

第一种常见的方式创建单例: 

/// <summary>
 /// 不安全的单例
 /// </summary>
 public sealed class singleton
 {
  private static singleton _singleton;
  private singleton() { }
  public static singleton getsingleton()
  {
   if (_singleton == null)
   {
    _singleton = new singleton();
   }
   return _singleton;
  }
 }

注:为什么说是不安全的单例,多线程访问时可能会new多个对象...

第二种方式创建单例:

/// <summary>
 /// (多线程)安全单例
 /// </summary>
 public sealed class singleton
 {
  private static singleton _singleton;
  private static readonly object obj = new object();
  private singleton() { }
  public static singleton getsingleton()
  {
   if (_singleton == null)
   {
    //加锁保护,在多线程下可以确保实例值被创建一次。缺点是每 次获取单例,都要进行判断,涉及到的锁和解锁比较耗资源。
    lock (obj)
    {
     if (_singleton == null)
     {
      _singleton = new singleton();
     }
    }

   }
   return _singleton;
  }
 }

注:为了解决上面第一种方式创建的不安全实例问题应用而生。

第三种方式创建单例:

/// <summary>
 /// 只读单例
 /// </summary>
 public sealed class singleton
 {
  private static readonly singleton instance = new singleton();
  private singleton() { }
  public static singleton instance
  {
   get
   {
    return instance;
   }
  }
 }
/// <summary>
 /// 基于上面的只读单例=自动属性只读单例(语法糖)
 /// </summary>
 public sealed class singleton
 {
  private singleton() { }
  public static singleton instance { get; } = new singleton();
 }

注:只读属性式=>借助readonly属性,instance只被初始化一次,同样达到了单例的效果。在引用函数执行第一句话之前,instance其实已经被赋值了,并不是预期的 只有到访问instance变量时才创建对象。

第四种方式创建单例:

/// <summary>
 /// singleton中加上静态构造函数。
 /// </summary>
 public sealed class singleton
 {
  public static readonly singleton instance = new singleton();
  private singleton()
  {
   console.writeline("初始化1!");
  }
  static singleton()
  {
  }
  public static singleton instance
  {
   get { return instance; }
  }
 }

注:为了解决(第三种只读属性实例)在执行第一句代码之前,实例已经被初始化问题。

第五种方式创建单例:

/// <summary>
 /// 使用lazy创建单例,默认是线程安全的
 /// </summary>
 public sealed class singleton
 {
  private static readonly lazy<singleton> instance = new lazy<singleton>(() => new singleton());//
  private singleton() { }
  public static singleton instance
  {
   get
   {
    return instance.value;
   }
  }
 }
// 贴一下关于上面lazy<t> s=new lazy<t>()参数的定义;
  // 摘要:
  // 初始化system.lazy`1类的新实例。 懒惰初始化时
   // 发生时,使用指定的初始化函数和初始化模式。
  
  // 参数:
  // valuefactory:
  // 被调用以生成延迟初始化值的委托是必需的参数
  //
  // isthreadsafe:
  //  如果要使此实例可由多个线程同时使用,则为true; false
         //使此实例一次只能由一个线程使用。
  public lazy(func<t> valuefactory, bool isthreadsafe);

以上就是c# 创建单例的多种方式的详细内容,更多关于c# 创建单例的资料请关注其它相关文章!

相关标签: c# 单例