10

I was reading a tutorial for implementing Singleton and the code is

public class Singleton
    {
        private static readonly Singleton instance = new Singleton();

        static Singleton()
        {
            Console.WriteLine("Static");
        }
        private Singleton()
        {
            Console.WriteLine("Private");
        }

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

        public void DoSomething() {
            //this must be thread safe
        }
    }

When I write Singleton.Instance, the output is

Private
Static

I was expecting it to be

Static
Private

Reason being that when I read a MSDN tutorial "https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx"

I saw that public constructor was called after the static constructor.

Why is there a difference?

Ahmad
  • 12,336
  • 6
  • 48
  • 88
Rajat
  • 410
  • 4
  • 19
  • 1
    For a singleton, you don't need a static constructor. Create a object and use simple threading using `lock(object)` so that only one thread can access your method. – ViVi Feb 14 '17 at 05:40
  • I started with Locks, and have read enough documentation claiming how expensive they are. Hence, I chose this code. – Rajat Feb 14 '17 at 05:41
  • @ViVi this question is not about what is the better way but simply why the output is `Private Static`. Good question – CodingYoshi Feb 14 '17 at 05:43
  • Check this [article](http://csharpindepth.com/Articles/General/Singleton.aspx). Inorder to ensure Singleton behavior, you have to lock it before creating a new instance, without which there is chance of 2 instance being created by 2 calls to `Instance`. – ViVi Feb 14 '17 at 05:44
  • @ViVi: the runtime provides the necessary lock when initializing the instance in the static field initializer (or in the static constructor, for that matter). No explicit lock is needed. – Peter Duniho Feb 14 '17 at 05:48
  • @PeterDuniho So is it better to follow this practice(static Constructor) than using the `lock` method with private constructor? – ViVi Feb 14 '17 at 05:51
  • 1
    @ViVi: it depends on a variety of factors, mainly how expensive the constructor of the singleton is, how likely the singleton is to be used. An infrequently-used singleton, with an expensive constructor, you would probably want to back with `Lazy` instead of initializing the field directly. Otherwise, I would just go with the straight field initializer. Either way, you let the runtime or framework deal with synchronization; since `Lazy` was introduced, there's never really been a good reason to write explicitly-locking code for singletons. – Peter Duniho Feb 14 '17 at 05:54
  • 1
    @ViVi: note that Jon Skeet's article, which you reference, even advises this exactly. Use a field initializer, or `Lazy` if you really need lazy initialization. – Peter Duniho Feb 14 '17 at 05:55
  • Possible duplicate of https://stackoverflow.com/questions/2925611/static-constructor-can-run-after-the-non-static-constructor-is-this-a-compiler – Peter Duniho Feb 14 '17 at 06:02

1 Answers1

6

The static constructor has to complete before code outside the class can use the class. But the language specification has to allow the instance constructor to complete before the static constructor does, so that you could e.g. do this:

static Singleton()
{
    instance = new Singleton();
    // It has to be legal to use "instance" here
    Console.WriteLine("Static");
}

Note that in your example, that's essentially what happens anyway. Field initializers essentially become part of the constructor; they just execute first.

This is corroborated by the generated IL:

// Static constructor
Singleton..cctor:
IL_0000:  newobj      Singleton..ctor     //Calls private constructor first
IL_0005:  stsfld      Singleton.instance  //to create .instance
IL_000A:  nop         
IL_000B:  ldstr       "Static"
IL_0010:  call        System.Console.WriteLine
IL_0015:  nop         
IL_0016:  ret         

See also related (but not duplicate) question and Eric Lippert's typically excellent answer here: Calling of Static Constructor and Instance Constructor

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • So it starts with static constructor as usual , inside static constructor it needs valid instance , so it goes to create the field instance which again calls the private constructor. Static-->Field--> Private constructor. Did i get that right? – Abdul Hameed Feb 14 '17 at 05:58
  • @Abdul: basically, yes. That's all determined at compile-time. It's not like the code literally dynamically determines in the static constructor it needs the valid instance. The code is already there to get it. But yes, it's the need to initialize the field in the static constructor that causes the instance constructor to be called. – Peter Duniho Feb 14 '17 at 06:04