7

I was going through the following Singleton implementation mentioned here. I understand static constructors get executed before the first static method call or before te object is instantiated, but did not understand its use here (even from the comments). Could anyone help me understand it?

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

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}
Nemo
  • 24,540
  • 12
  • 45
  • 61
  • 2
    It's explained in the bullet points underneath it, specifically: `The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called 'beforefieldinit'. Unfortunately, the C# compiler (as provided in the .NET 1.1 runtime, at least) marks all types which don't have a static constructor (i.e. a block which looks like a constructor but is marked static) as 'beforefieldinit'.` So, he wants the `new Singleton()` to be constructed as late as possible (lazily), and the only way to get the C# compiler to do this is to provide an empty static constructor. – porges Mar 16 '12 at 03:18
  • Forgive my ignorance. What is "laziness of type initializers". It is initialization upon first request? – Nemo Mar 16 '12 at 03:31
  • Exactly. It's only guaranteed in that situation, otherwise the runtime can run the type initializers whenever it wants to, such as as soon as the type is loaded. For a longer explanation see the link in Jay's answer. – porges Mar 16 '12 at 03:34

1 Answers1

8

The static constructor is not there in order that it should be called before or after anything else, only as a way to make the compiler not set the beforefieldinit flag.

More information on this here: What does beforefieldinit flag do?

The rationale is to achieve a measure of laziness in the initialization of the singleton object. If beforefieldinit is set (because no static constructor is defined), then executing a method that conditionally references Singleton.Instance is likely to initialize the singleton object, even if the condition is not satisfied and that call is never made.

public void Foo()
{
    if (false)
    {
        var bar = Singleton.Instance.SomeMethod();
    }
}

On the other hand, if beforefieldinit is not set (because a static constructor is defined -- even an empty one), then executing that same method will only cause the singleton instance to be initialized if the condition is satisfied and that call is actually made.

That article goes on to point out that this particular implementation is not fully lazy because calling any other static member that you define on the singleton class will also cause Instance to be initialized.

Community
  • 1
  • 1
Jay
  • 56,361
  • 10
  • 99
  • 123