C# - 单例模式

CSh*_*ner 7 c# singleton static constructor

正如你从我的昵称中看到的,我是新手,实际上是在了解Singleton模式,我遇到了一个问题.在我了解到静态构造函数总是在标准构造函数之前执行之前,但在下面的代码中,结果是不同的,首先我看到"Insta"字符串然后是"静态",为什么会发生?

sealed class Singleton
{
    private static readonly Singleton instance;

    private Singleton()
    {
        Console.WriteLine("Insta");
    }

    static Singleton()
    {
        instance  = new Singleton();
        Console.WriteLine("Static");
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

class Program
{
    static void Main()
    {
        Singleton s1 = Singleton.Instance;

    }

}
Run Code Online (Sandbox Code Playgroud)

Tig*_*ran 13

如果你会写

static Singleton()
{
    Console.WriteLine("Static"); //THIS COMES FIRST
    instance  = new Singleton();

}
Run Code Online (Sandbox Code Playgroud)

你会看到你的期望

静态构造函数是在第一次执行,符合市场预期,但你在控制台打印instance = new Singleton();线,但该行执行的实例构造函数,所以"出师表".

所以执行流程:

  • 静态的
    • instance = new Singleton();
      • 实例ctor打印"insta"
    • "静态的"


saa*_*rim 9

有关单例模式的质量说明,请参见此处MSDN模式.

MSDN建议你应该写如下,所以它是线程安全的:

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这种模式比静态构造函数具有以下优势:

在对象请求实例之前不执行实例化; 这种方法称为惰性实例化.延迟实例化避免在应用程序启动时实例化不必要的单例.

看看这是否符合您的需求,如果是,请实施此解决方案.

  • 线程安全与这个概念性问题有什么关系? (2认同)
  • 我的观点是介绍如何实现单例解决方案的MSDN文章.无需重新发明轮子.由于他是一名初学者,因此有一篇好的文章来阅读和理解特定的模式总是好的. (2认同)