C# - Singleton Pattern

2019-06-17 07:41发布

As you can see from my nickname I'm newbie actually learning about Singleton pattern, where I got one problem. 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 ?

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;

    }

}

3条回答
做自己的国王
2楼-- · 2019-06-17 07:50

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");
    }
查看更多
老娘就宠你
3楼-- · 2019-06-17 07:59

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(); line, but this line execute instance ctor, so "inst".

So execution flow:

  • static ctor
    • instance = new Singleton();
      • instance ctor prints "insta"
    • "static"
查看更多
Lonely孤独者°
4楼-- · 2019-06-17 08:07

See the MSDN pattern here for a quality explanation of the singleton pattern.

MSDN recommends you should write it as below so it is thread safe:

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.

查看更多
登录 后发表回答