I wrote an article on the basics of Design Patterns in C#. Now it is time to discuss Singleton Design Pattern in C#.
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.
How to Implement Singleton Pattern in your code
There are many ways to implement a Singleton Pattern in C#.
- No Thread Safe Singleton.
- Thread-Safety Singleton.
- Thread-Safety Singleton using Double-Check Locking.
- Thread-Safe Singleton without using locks and no lazy instantiation.
- Fully lazy instantiation.
- Using .NET 4's Lazy
type.
No Thread Safe Singleton
- The following code is not thread-safe.
- Two different threads could both have evaluated the test (if instance == null) and found it to be true, then both create instances, which violates the singleton pattern.
// Bad code! Do not use it!
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;
}
}
}
Thread Safety Singleton
- This implementation is thread-safe.
- In the following code, the thread is locked on a shared object and checks whether an instance has been created or not.
- This takes care of the memory barrier issue and ensures that only one thread will create an instance.
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;
}
}
}
}
Thread Safety Singleton using Double Check Locking
- 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;
}
}
}
Example:
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;
}
}
}
İlk Yorumu Siz Yapın