4

when i go through the below code, i couldnt find the reason why it using private constructor in the sample?

public sealed class Singleton
    {
        private static Singleton instance = null;
        private Singleton()
        {
        }

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

                return instance;
            }
        }
    } 

...

  //Why shouldnt I use something like below.
  public class Singleton
  {
       private static Singleton instance = null;            

       static Singleton()
       {
       }

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

                return instance;
            }
        }
    } 

instead of public class if i created a static class, i can use the class directly rather than creating instance. what is the need of creating a private constructor here, when the static keyword persists to the same job?

any other advantage for following this pattern?

Tom Cruise
  • 1,395
  • 11
  • 30
  • 58
  • https://www.michaelsafyan.com/tech/design/patterns/singleton – Idos Mar 15 '16 at 07:55
  • This isn't a singleton, there are no instance methods. The private constructor simply prevents client code creating an instance (which isn't needed for anything). The static modifier for classes was only introduced in C# 2 - perhaps the code predates this or the author was unaware of it. – Charles Mager Mar 15 '16 at 08:04
  • I have updated the code. – Tom Cruise Mar 15 '16 at 08:48
  • do not use *static constructors* i.e. `static Singleton()` unless you have to. – Dmitry Bychenko Mar 15 '16 at 09:07

7 Answers7

5

A singleton class and a static class are different things, and it seems you're mixing that up. A static class has only static methods and static members and therefore cannot have a constructor. Static methods are called on the type, not the instance.

A singleton class, in contrast, has normal methods and is called using an instance. The private constructor is there to prevent creating multiple instances of the class and usually used by a private property that returns this only instance.

public class Singleton
{ 
    static Singleton s_myInstance = null;
    private Singleton()
    {
    }

    // Very simplistic implementation (not thread safe, not disposable, etc)
    public Singleton Instance 
    {
        get 
        { 
             if (s_myInstance == null) 
                   s_myInstance = new Singleton();
             return s_myInstance;
        }
     }
     // More ordinary members here. 
}

The advantage of singletons is that they can implement interfaces. Also, they should be preferred over static classes if they are stateful (have many members), as having many static fields in a static class is quite ugly design.

PMF
  • 14,535
  • 3
  • 23
  • 49
  • Please, mark out that your implementation is the simplest one and thus not thread safe, or provide a standard thread safe version. – Dmitry Bychenko Mar 15 '16 at 08:11
  • 1
    Ok. The question was so basic that I thought to prefer the really basic implementation. – PMF Mar 15 '16 at 08:16
  • why cant i use a static constructor in the code you gave as an example? that too will invoke only once. – Tom Cruise Mar 15 '16 at 08:28
  • That's also possible, however not usually done, as it could result in the instance being created even if it is never used. – PMF Mar 15 '16 at 08:56
3

Since Singleton can have one instance only, you have to prevent second instance creation. If you skip constructor declaration, e.g.

  public class clsSingleTon {
  }

one can call a default constructor:

  var one = new clsSingleTon();
  var two = new clsSingleTon(); // <- that's we try to ban

if you declare constructor being public, one can call it, so the only option is private one:

  public class clsSingleTon {
     public static int intcounter;

     // No-one will call it
     private clsSingleTon() {
     } 
     ...
  }

however, it seems that you don't want any instances at all, so drop the constructor and declare the class as static:

  // Static class - no instances are allowed 
  public static class clsSingleTon {
    //TODO: turn it into property
    public static int intcounter;

    public static void Hit() {
    }

    //TODO: turn it into property, do not mimic Java
    public static int getTotalHits() {
      return intCouner;
    }
  }

  ...

  clsSingleTon.Hit();
  MessageBox.Show(clsSingleTon.getTotalHits().ToString());
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • sorry..i am not clear what you are trying to convey.. My question was what is wrong in creating a static class instead of private constructor. exactly what you did in last snippet. – Tom Cruise Mar 15 '16 at 08:12
  • @Ammu: in your current implementation (taken from Java?) you *don't have* a static class (Java don't allow static classes) and thus the only option to prevent instance creation is to hide the constructor. In C# *static class* is preferable implementation (no *boiler plate* code); another issue is combining `intcounter` and `getTotalHits()` into *property* – Dmitry Bychenko Mar 15 '16 at 08:16
  • @ Dmitry Bychenko what is the need of combining intcounter and getTotalHits? why cant i use the same way that you mentioned in your answer? – Tom Cruise Mar 15 '16 at 08:21
  • @Ammu: sure you can, but property makes your code more *readable* (in C# we expect method to be an *active doer*, say it calls database and return `TotalHits` while property accessor is hardly more than *field reader*) more safier - in your current design one can put, say `clsSingleTon.intcounter = -12345;` do you want to allow this? Less perplexing: what's the difference between `clsSingleTon.intcounter;` and `clsSingleTon.getTotalHits();`? – Dmitry Bychenko Mar 15 '16 at 08:26
  • Can you please check the updated code in the question. I have taken this from a website. – Tom Cruise Mar 15 '16 at 08:50
  • @Ammu: in your updated sample *Why shouldnt I use...* you don't put `static` but `sealed` class: `public sealed class Singleton {...`. And you've *skipped* the constructor so anyone can easily create the *second instance* with *default constructor* (see my answer). According your code, you don't want any instances at all, so make class being *static* and drop constructor. – Dmitry Bychenko Mar 15 '16 at 09:01
  • Ok. I understood. I made the class as public. In this case is it possible? – Tom Cruise Mar 15 '16 at 10:40
  • @Ammu: yes, *static class* like any other class can be `public` – Dmitry Bychenko Mar 15 '16 at 10:43
  • Thank you. Please confirm the second code snippet also will do what singleton pattern does. – Tom Cruise Mar 15 '16 at 18:29
  • @Ammu: The *second* snippet in the question *is not* a *Singleton* since *static constructor* (i.e. `static Singleton() {}`) doesn't hide *default* one, so anyone can create a second instance by `new Singleton();`. You want either a *private* constructor or (*better choice*) a *static class*. – Dmitry Bychenko Mar 16 '16 at 06:52
  • Can you please elaborate how i can define singleton using static class? Please provide an example. – Tom Cruise Mar 16 '16 at 15:42
  • @Ammu: technically, you *can't*: Singleton *must* have *one instance*, while static class *can't have any*. Since you don't want instances, static class is a solution for you however the solution is not a classic singleton pattern. – Dmitry Bychenko Mar 16 '16 at 15:51
  • Agree with your point. But though its not classic singleton pattern, will it give the same result? – Tom Cruise Mar 17 '16 at 04:43
  • @Ammu: since you call *static methods only*, the result will be the same. – Dmitry Bychenko Mar 17 '16 at 06:30
0

Singelton provides you the facility to implement the interfaces

Singelton pattren has wide usage specialy where you have to limit your application to create only one instance just like in many games you have only one instance

Hassan Tariq
  • 730
  • 7
  • 15
0

Original pattern was devised before C# and .net, see http://www.blackwasp.co.uk/gofpatterns.aspx

Canonical implementation was in c++, which doesn't have static classes, therefore you had to use private constructor trick in order to control class instantiation

Maksim Satsikau
  • 1,444
  • 11
  • 11
0

There is a private constructor so it can be called only within the class. Then you will have to define a static method which will 'lock' your class and instantiate it.

nicecatch
  • 1,687
  • 2
  • 21
  • 38
0

In an ideal OOP world, you should have no static classes. This is because:

You can't have instances of static classes. This alone goes against most of OOP principles and design patterns. Just open a list of design patterns, go through them one by one, and ask yourself - can I do this without having an instance of a class? If the answer is no - you have an advantage on using a singleton pattern over a static class.


As for using a private constructor - read the answer by Dmitry Bychenko.

Community
  • 1
  • 1
Gediminas Masaitis
  • 3,172
  • 14
  • 35
0

A private constructor is not solely tied to a singleton class. Even with a class that is meant to have multiple instances, using a public constructor results in a distributed memory allocation model (i.e. control of allocating memory is in the hands of any code that can call 'new()'). If, instead, you have a private constructor and a public (static) factory method, memory allocation can be centralized. There are many cases where you use private constructors.

  1. You have a utility class which exposes only static util functions, for example a helper class to convert rest models to db models and vice versa, a class which has all String literals being used by your application. Since all the methods/fields are public static there is no meaning of an object of this class.

  2. You want only one instance of a class not because you are trying to save memory, rather you want all components in your application to use same instance, for example db connection manager, an in-memory cache implementation, etc.

Source: https://en.wikipedia.org/wiki/Singleton_pattern