Singleton Design Pattern in C#

I have decided to write an article on design partners in C#. You can see my previous article on following link.

Design Patterns in C#: http://www.c-sharpcorner.com/Blogs/12407/design-patterns-in-C-Sharp.aspx
 
Please go through the example at the end of this article so that you understand the Singleton Design Pattern better.
 
Now it's time for the Singleton Design Pattern. Here we go.
 
What is Singleton Design Pattern?

  1. Ensures a class has only one instance and provides a global point of access to it.
  2. A singleton is a class that only allows a single instance of itself to be created, and usually gives simple access to that instance.
  3. Most commonly, singletons don't allow any parameters to be specified when creating the instance, since a second request of an instance with a different parameter could be problematic! (If the same instance should be accessed for all requests with the same parameter then the factory pattern is more appropriate.)
  4. There are various ways to implement the Singleton Pattern in C#. The following are the common characteristics of a Singleton Pattern.
  • A single constructor, that is private and parameterless.
  • The class is sealed.
  • A static variable that holds a reference to the single created instance, if any.
  • A public static means of getting the reference to the single created instance, creating one if necessary.

Advantages

The advantages of a Singleton Pattern are:

  1. Singleton pattern can be implemented interfaces.
  2. It can be also inherit from other classes.
  3. It can be lazy loaded.
  4. It has Static Initialization.
  5. It can be extended into a factory pattern.
  6. It helps to hide dependencies.
  7. It provides a single point of access to a particular instance, so it is easy to maintain.

Disadvantages

The disadvantages of a Singleton Pattern are:

  1. Unit testing is more difficult (because it introduces a global state into an application).
  2. This pattern reduces the potential for parallelism within a program, because to access the singleton in a multi-threaded system, an object must be serialized (by locking).

Singleton class vs. Static methods

The following conpares Singleton class vs. Static methods:

  1. A Static Class cannot be extended whereas a singleton class can be extended.
  2. A Static Class can still have instances (unwanted instances) whereas a singleton class prevents it.
  3. A Static Class cannot be initialized with a STATE (parameter), whereas a singleton class can be.
  4. A Static class is loaded automatically by the CLR when the program or namespace containing the class is loaded.

How to Implement Singleton Pattern in your code:
 
There are many way to implement a Singleton Pattern in C#.

  1. No Thread Safe Singleton.
  2. Thread-Safety Singleton.
  3. Thread-Safety Singleton using Double-Check Locking.
  4. Thread-Safe Singleton without using locks and no lazy instantiation.
  5. Fully lazy instantiation.
  6. Using .NET 4's Lazy<T> type.

1. No Thread Safe Singleton:

Explanation of the following code:

  1. The following code is not thread-safe.
  2. Two different threads could both have evaluated the test (if instance == null) and found it to be true, then both creates instances, which violates the singleton pattern.
  3. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed.

// Bad code! Do not use!

public sealed class Singleton

{

    //Private Constructor.

    private Singleton()

    {

    }

 

    private static Singleton instance = null;

    public static Singleton Instance

    {

        get

        {

            if (instance == null)

            {

                instance = new Singleton();

            }

            return instance;

        }

    }

}
 

2. Thread Safety Singleton
 
Explanation of the following code:

  1. This implementation is thread-safe.
  2. In the following code, the thread is locked on a shared object and checks whether an instance has been created or not.
  3. This takes care of the memory barrier issue and ensures that only one thread will create an instance.
  4. For example: Since only one thread can be in that part of the code at a time, by the time the second thread enters it, the first thread will have created the instance, so the expression will evaluate to false.
  5. The biggest problem with this is performance; performance suffers since a lock is required every time an instance is requested.

public sealed class Singleton

{

    Singleton()

    {

    }

 

    private static readonly object padlock = new object();

 

    private static Singleton instance = null;

    public static Singleton Instance

    {

        get

        {

            lock (padlock)

            {

                if (instance == null)

                {

                    instance = new Singleton();

                }

                return instance;

            }

        }

    }

}
 

3. Thread Safety Singleton using Double Check Locking
 
Explanation of the following code:

  1. In the following code, the thread is locked on a shared object and checks whether an instance has been created or not with double checking.

public sealed class Singleton

{

    Singleton()

    {

    }

 

    private static readonly object padlock = new object();

 

    private static Singleton instance = null;

    public static Singleton Instance

    {

        get

        {

            if (instance == null)

            {

                lock (padlock)

                {

                    if (instance == null)

                    {

                        instance = new Singleton();

                    }

                }

            }

            return instance;

        }

    }

}

  

4. Thread Safe Singleton without using locks and no lazy instantiation
 
Explanation of the following code:

  1. The preceding implementation looks like very simple code.
  2. This type of implementation has a static constructor, so it executes only once per Application Domain.
  3. It is not as lazy as the other implementation.

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;

        }

    }

}
 

5. Fully lazy instantiation
 
Explanation of the following code:

  1. Here, instantiation is triggered by the first reference to the static member of the nested class, that only occurs in Instance.
  2. This means the implementation is fully lazy, but has all the performance benefits of the previous ones.
  3. Note that although nested classes have access to the enclosing class's private members, the reverse is not true, hence the need for instance to be internal here.
  4. That doesn't raise any other problems, though, as the class itself is private.
  5. The code is more complicated in order to make the instantiation lazy.

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;

        }

    }

}


 

6. Using .NET 4's Lazy<T> type
 
Explanation of the following code:

  1. If you're using .NET 4 (or higher) then you can use the System.Lazy<T> type to make the laziness really simple.
  2. All you need to do is pass a delegate to the constructor that calls the Singleton constructor, which is done most easily with a lambda expression.
  3. It also allows you to check whether or not the instance has been created with the IsValueCreated property.

public sealed class Singleton

{

    private Singleton()

    {

    }

    private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance

    {

        get

        {

            return lazy.Value;

        }

    }

}
 

Example:
 
The final example is here:

namespace Singleton

{

    class Program

    {

        static void Main(string[] args)

        {

            Calculate.Instance.ValueOne = 10.5;

            Calculate.Instance.ValueTwo = 5.5;

            Console.WriteLine("Addition : " + Calculate.Instance.Addition());

            Console.WriteLine("Subtraction : " + Calculate.Instance.Subtraction());

            Console.WriteLine("Multiplication : " + Calculate.Instance.Multiplication());

            Console.WriteLine("Division : " + Calculate.Instance.Division());

 

            Console.WriteLine("\n----------------------\n");

 

            Calculate.Instance.ValueTwo = 10.5;

            Console.WriteLine("Addition : " + Calculate.Instance.Addition());

            Console.WriteLine("Subtraction : " + Calculate.Instance.Subtraction());

            Console.WriteLine("Multiplication : " + Calculate.Instance.Multiplication());

            Console.WriteLine("Division : " + Calculate.Instance.Division());

 

            Console.ReadLine();

        }

    }

 

    public sealed class Calculate

    {

        private Calculate()

        {

        }

        private static Calculate instance = null;

        public static Calculate Instance

        {

            get

            {

                if (instance == null)

                {

                    instance = new Calculate();

                }

                return instance;

            }

        }

 

        public double ValueOne { get; set; }

        public double ValueTwo { get; set; }

 

        public double Addition()

        {

            return ValueOne + ValueTwo;

        }

 

        public double Subtraction()

        {

            return ValueOne - ValueTwo;

        }

 

        public double Multiplication()

        {

            return ValueOne * ValueTwo;

        }

 

        public double Division()

        {

            return ValueOne / ValueTwo;

        }

    }

}
 
Please write your feedback on this article.

Up Next
    Ebook Download
    View all
    Learn
    View all