Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton implementation laziness with static constructor

Jon Skeet suggests in his singleton implementation that if you require the maximum laziness for your singleton you should add a static constructor which will make the compiler mark the type as beforefieldinit.

However, I did some testing and it seems that it's more lazy without the beforefieldinit.

Code sample (the private constructor call outputs to console and verifies that the fields were initialized:

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

    public static string Stub()
    {
        return "123";
    }

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    //static Singleton()
    //{
    //}
    private Singleton()
    {
        Console.WriteLine("private ctor");
    }

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

When I call Singleton.Stub() the private constructor is not being hit, and when I uncomment the static constructor, the private constructor is always called.

This is the only difference I could track made by the static constructor.

In my attempts to understand what difference will the beforefieldinit do I've also read Skeet's answer in this post tried it with passing false to DoSomething() - with or without the static constructor the private constructor is not being called.

public static void DoSomething(bool which)
{
    if (which)
    {
        var a = Singleton.Stub();
    }
    else
    {
        Faketon.Stub();
    }
}
like image 279
BornToCode Avatar asked May 24 '16 14:05

BornToCode


People also ask

Does singleton allow lazy initialization?

Lazy initialization is possible. It is also thread safe.

What is one of the most common mistakes you can make when implementing a singleton?

A common mistake with that implementation is to neglect synchronization, which can lead to multiple instances of the singleton class.

What if I use static instead making singleton?

While a static class is generally initialized when it is first loaded and it will lead to potential class loader issues. Singleton Objects stored on heap while static class stored in stack. Singleton Objects can have constructor while Static Class cannot.

Is lazy singleton thread safe?

Is singleton thread safe? A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialized object.


1 Answers

When I call Singleton.Stub() the private constructor is not being hit, when I uncomment the static ctor private constuctor is always called.

It's not clear what the value of which is here, but fundamentally you've got four cases:

  • Static constructor, Singleton.Stub called: type initializer is guaranteed to run
  • Static constructor, Singleton.Stub not called: type initializer is guaranteed not to run
  • No static constructor, Singleton.Stub called: type initializer may run, but isn't guaranteed to
  • No static constructor, Singleton.Stub not called: type initializer may run, but isn't guaranteed to

The last two cases only differ in that if you change Singleton.Stub to use a static field, the third case becomes "type initializer is guaranteed to run".

like image 101
Jon Skeet Avatar answered Sep 29 '22 07:09

Jon Skeet