2

What if, I replaced private constructor with a static constructor in singleton Design pattern?

public sealed class Singleton
{
    private static Singleton instance=null;

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (instance==null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

Static constructor will be called only once and I couldn't find any difference in the implementation. Can we replace private with static constructor?

JasCav
  • 34,458
  • 20
  • 113
  • 170
Tom Cruise
  • 1,395
  • 11
  • 30
  • 58
  • Pretty sure an having both an empty private and empty static constructor would compile down to the same IL impl. – Tdorno Aug 25 '16 at 00:05
  • No. I will not have both the constructor. Im concerned about the need of private constructor here. why cant we use static instead? – Tom Cruise Aug 25 '16 at 00:06
  • 1
    Completely besides the point, but your current Singleton implementation is broken as it's not thread safe. – sstan Aug 25 '16 at 00:48
  • Usefull [article](http://csharpindepth.com/Articles/General/Singleton.aspx) about different implementation possible ;-) – Sehnsucht Aug 25 '16 at 01:24

5 Answers5

8

All that the private constructor is really doing in this case is preventing anything outside of the class from instantiating an instance of class Singleton, which is almost certainly intentional as a singleton should only have a single instance.

Static class constructors are run once for a type, at an unknown time, before the type, or any of it's static members, is to be utilized. Static fields are initialized before the static constructor would be run.

So, I suppose you could replace the constructor with a static one, but that would then give you the implicit parameter-less constructor on the Singleton Type, which would allow anyone to instantiate an instance, which is likely at odds with why you are using the singleton pattern in the first place. It also wouldn't change anything about how your class was being constructed, really, so why do it?

Take the following class as an example:

public class Test { }

Under the covers, because there is no declared constructor, the C# compiler implicitly adds a parameterless, public constructor to the class, allowing consumers to create an instance.

public class Program {
    public static void Main() { 
        var test = new Test();
    }
}

This is all fine and good if you want to be able to make instances of your class. The singleton pattern intends to only provide a single instance of a type to the consumers. We could add this static instance to our test type like so:

public class Test { public static Test Instance {get;} = new Test(); }

and we would be able to get this static instance like so:

public class Program {
    public static void Main() {
        var test = Test.Instance; // good
        var other = new Test(); // less than ideal
    }
}

So we are providing access to our singleton object through it's instance field, as expected, but we can still create instances of the singleton type, which is less good, as it goes against the purpose of a singleton (namely, having only a single shared instance.)

So we add a private, parameterless constructor to the type.

public class Test { 
    private Test() {}
    public static Test Instance {get;} = new Test(); 
}

Adding a constructor to a type will cause the C# compiler not to add an implicit public parameter-less constructor. Making it private allows it to be accessed within the class scope, which is used for instantiating our instance property, and prevents anything else from instantiating the object. The end result being:

public class Program {
    public static void Main() {
        var test = Test.Instance; // good
        var other = new Test(); // Compile time error
    }
}

Your singleton object now prevents other instances of the class from being instantiated, and the only way to use it is through the instance property as intended.

Jonathon Chase
  • 9,396
  • 21
  • 39
2

In simple terms, if you remove the private constructor, then anyone will be able to create a new instance of Singleton:

// With the private constructor, the compiler will prevent this code from working.
// Without it, the code becomes legal.
var newInstance = new Singleton();

And if anyone can instantiate Singleton as above, then you no longer have a singleton.

sstan
  • 35,425
  • 6
  • 48
  • 66
0

Another cleaner way to do it is to use readonly on you private instance.

This is less code and also thread safe. The CLR takes care of everything for you, no need for lock , check for null and stuff.

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

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

    private Singleton()
    {
    }
}

Then simply test:

[TestMethod]
public void IsSingleton()
{
    Assert.AreSame(Singleton.Instance, Singleton.Instance);
}

EDIT:

example using lock

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

    public static Singleton Instance
    {
        get
        {
            lock(_lock)
            {
                if (instance==null)
                {
                    instance = new Singleton();
                }
                return instance;    
            }
        }
    }

    private Singleton()
    {
    }
}
meda
  • 45,103
  • 14
  • 92
  • 122
  • The only issue with doing it this way is that you eagerly create the instance. The OP's method is lazy in terms of creating the instance. That might be preferred in some circumstances. – Enigmativity Aug 25 '16 at 01:01
  • The only reason I could think to use the backing field over readonly auto-properties is if you are in a project that is strictly C# 5 or below. – Jonathon Chase Aug 25 '16 at 01:05
  • @JonathonChase exactly, I also added an example using `lock` if OP prefer that – meda Aug 25 '16 at 01:08
0

In simplest terms, if you remove private, the default public constructor will get exposed. Then outsiders will be allowed to use new Singleton(); and make number of instances of Singleton class. So no Singleton Pattern will be there.

Additionally this classic implementation of Singleton pattern (private constructor + static getInstance() with either lazy-loading or eager loading) is so evil. In modern day you must switch to a Dependency-Injection framework instead.

Community
  • 1
  • 1
Supun Wijerathne
  • 11,964
  • 10
  • 61
  • 87
-2

This should work just fine. You could also make the class static and generic so you can store whatever kind of value in instance you want it to hold. This would facilitate the separation of concerns, keeping the singleton pattern and the class that it will contain separate.

buchWyrm
  • 127
  • 10