Lazy init singleton

I’ve seen some confusion in some MS internal mailing lists about when singletons are instantiated for the pattern described in:

 

https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/singletondespatt.asp

 

 

// .NET Singleton

sealed class Singleton

{

    private Singleton() {}

    public static readonly Singleton Instance = new Singleton();

}

 

The confusion comes from trying to understand when the singleton’s instance is created. The article states:

 

‘What we really care about is that we get the instance created either on or just before the first call to (in this case) the Instance property, and that we have a defined initialization order for static variables in a class’

 

With the code above, the correct answer is ‘Whenever the CLR decides so, as long as it happens before the first use of Singleton.Instance’. This is not what you really want if your singleton is bringing in some expensive resource and the text in the article if not wrong, may be a bit misleading.

 

The following counterexample initializes the singleton even if we will never call Instance.

 

using System;

 

sealed class Singleton

{

    private Singleton()

    {

            Console.WriteLine("Singleton initialized");

    }

   

    public void Method()

    {

            Console.WriteLine("Method");

    }

    public static readonly Singleton Instance = new Singleton();

}

 

class Test

{

            static public bool bFalse = false;

            static public void Main()

            {

                        if (bFalse)

                        {

                                    Singleton.Instance.Method();

                        }

            }

}

 

Why?

 

The compiler embeds the static initialization

 

public static readonly Singleton Instance = new Singleton();

 

inside the class constructor (.cctor) of the class Singleton. So the question now is ‘when does the .cctor get run’. I go over this in https://blogs.msdn.com/davidnotario/archive/2005/02/08/369593.aspx . If you really want a singleton that only gets created on first access, you want the Singleton type to have precise init. You would do it this way:

 

 

sealed class Singleton

{

    Static Singleton()

    {

    }

    private Singleton()

    {

            Console.WriteLine("Singleton initialized");

    }

   

    public void Method()

    {

            Console.WriteLine("Method");

    }

    public static readonly Singleton Instance = new Singleton();

}

 

Now, note this behavior may come at the expense of runtime checks (that ask the 'did my .cctor run already?' question), whereas with beforefieldinit semantics, the .cctor gets run aggressively by the JIT (at compile time) and no checks need to be inserted (so maybe you want 2 singleton classes, Singleton and ExpensiveResourceSingleton, depending on your needs).