@Learner Since its a interview question and mostly in India they ask to write to Psuedo code to evaluate the candidate coding skills, I try to fit myself in the candidate shoes to give the answer.
Well design patterns has evolved over a period of time with advancements in the programming language and Singleton is not a exception. There are many ways that we can create a Singleton class using C#. I would like to showcase few of the flavors that I can able to recollect
1. Plain vanilla Singleton without Thread-Safety
public sealed class Singleton
{
private Singleton()
{
}
private static Singleton instance = null;
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
2. Singleton with Thread Saftey
public sealed class Singleton_ThreadLock
{
Singleton_ThreadLock()
{
}
private static readonly object padlock = new object();
private static Singleton_ThreadLock instance = null;
public static Singleton_ThreadLock Instance
{
get
{
// Uses the lock to avoid another resource to create the instance in parallel
lock (padlock)
{
if (instance == null)
{
instance = new Singleton_ThreadLock();
}
return instance;
}
}
}
}
3. Singleton - Double Thread Safe
public sealed class Singleton_DoubleThreadSafe
{
Singleton_DoubleThreadSafe()
{
}
private static readonly object padlock = new object();
private static Singleton_DoubleThreadSafe instance = null;
public static Singleton_DoubleThreadSafe Instance
{
get
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton_DoubleThreadSafe();
}
}
}
return instance;
}
}
}
4. Singleton - Early Initialization
public sealed class Singleton_EarlyInitialization
{
private static readonly Singleton_EarlyInitialization instance = new Singleton_EarlyInitialization();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton_EarlyInitialization()
{
}
private Singleton_EarlyInitialization()
{
}
public static Singleton_EarlyInitialization Instance
{
get
{
return instance;
}
}
}
5. Singleton - Lazy Initialization using .Net 4.0+ Framework
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;
}
}
}
Caveats:
- Well there are few people who create instance of the class using reflection (I did in one of my framework) but his can also be avoided. There are few samples in net that can show how to avoid it
- Its always best practice to make the Singleton class as sealed as it will restrict developers from inheriting the class.
- There are lots of IOC's in the market that can create Singleton instance of a normal class without following the above Singleton implementation.