简体   繁体   English

C# - 单例模式

[英]C# - Singleton Pattern

As you can see from my nickname I'm newbie actually learning about Singleton pattern, where I got one problem. 正如你从我的昵称中看到的,我是新手,实际上是在了解Singleton模式,我遇到了一个问题。 Before I've learned that static constructors are always executed before the standard constructors, but in this code below, the result is different, first I see the "Insta" string then the "Static", why does it happen ? 在我了解到静态构造函数总是在标准构造函数之前执行之前,但在下面的代码中,结果是不同的,首先我看到“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;

    }

}

If you will write 如果你会写

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

}

you would see what you expect 你会看到你的期望

static ctor is executed at first, as expected, but you print on console after the instance = new Singleton(); 首先执行static ctor,正如预期的那样,但是在instance = new Singleton(); 之后你在控制台上打印instance = new Singleton(); line, but this line execute instance ctor, so "inst". line,但是这行执行实例ctor,所以“inst”。

So execution flow: 所以执行流程:

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

See the MSDN pattern here for a quality explanation of the singleton pattern. 有关单例模式的质量说明,请参见此处MSDN模式。

MSDN recommends you should write it as below so it is thread safe: 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;
      }
   }
}

By the way, this pattern has the following advantage over static constructor: 顺便说一句,这种模式比静态构造函数具有以下优势:

The instantiation is not performed until an object asks for an instance; 在对象请求实例之前不执行实例化; this approach is referred to as lazy instantiation. 这种方法称为惰性实例化。 Lazy instantiation avoids instantiating unnecessary singletons when the application starts. 延迟实例化避免在应用程序启动时实例化不必要的单例。

See if this feets your need, and if so, implement this solution. 看看这是否符合您的需求,如果是,请实施此解决方案。

The static method is invoked first. 首先调用静态方法。 Here's the proof--change your code to the following: 这是证明 - 将您的代码更改为以下内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM