Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to implement a Singleton design pattern in C#?
The Singleton design pattern belongs to the Creational type pattern. It ensures that only one instance of a particular class is created throughout the application lifecycle. This single instance coordinates actions across the application and provides global access to shared resources.
The Singleton pattern is useful when you need exactly one instance of a class, such as for logging, caching, thread pools, or configuration settings.
Implementation Guidelines
Declare all constructors as
privateto prevent external instantiation.Provide a static property or method that returns the single instance.
Store the instance in a static field to ensure single creation.
Use
sealedkeyword to prevent inheritance.
Syntax
Following is the basic syntax for implementing a Singleton pattern −
public sealed class Singleton {
private static Singleton instance = null;
private Singleton() {
// Private constructor
}
public static Singleton GetInstance {
get {
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
Basic Singleton Implementation
Here is a simple implementation of the Singleton pattern −
using System;
public sealed class Singleton {
private static int counter = 0;
private static Singleton instance = null;
public static Singleton GetInstance {
get {
if (instance == null)
instance = new Singleton();
return instance;
}
}
private Singleton() {
counter++;
Console.WriteLine("Counter Value " + counter.ToString());
}
public void PrintDetails(string message) {
Console.WriteLine(message);
}
}
class Program {
static void Main() {
Singleton fromFacebook = Singleton.GetInstance;
fromFacebook.PrintDetails("From Facebook");
Singleton fromTwitter = Singleton.GetInstance;
fromTwitter.PrintDetails("From Twitter");
Console.WriteLine("Are both instances the same? " +
ReferenceEquals(fromFacebook, fromTwitter));
}
}
The output of the above code is −
Counter Value 1 From Facebook From Twitter Are both instances the same? True
Thread-Safe Singleton Implementation
The basic implementation is not thread-safe. Here's a thread-safe version using lock −
using System;
public sealed class ThreadSafeSingleton {
private static ThreadSafeSingleton instance = null;
private static readonly object lockObject = new object();
public static ThreadSafeSingleton GetInstance {
get {
lock (lockObject) {
if (instance == null)
instance = new ThreadSafeSingleton();
return instance;
}
}
}
private ThreadSafeSingleton() {
Console.WriteLine("Thread-safe Singleton instance created");
}
public void DoWork() {
Console.WriteLine("Performing work in thread-safe singleton");
}
}
class Program {
static void Main() {
ThreadSafeSingleton instance1 = ThreadSafeSingleton.GetInstance;
instance1.DoWork();
ThreadSafeSingleton instance2 = ThreadSafeSingleton.GetInstance;
instance2.DoWork();
Console.WriteLine("Same instance? " + ReferenceEquals(instance1, instance2));
}
}
The output of the above code is −
Thread-safe Singleton instance created Performing work in thread-safe singleton Performing work in thread-safe singleton Same instance? True
Lazy Initialization Singleton
C# provides Lazy<T> for thread-safe lazy initialization −
using System;
public sealed class LazySingleton {
private static readonly Lazy<LazySingleton> lazy =
new Lazy<LazySingleton>(() => new LazySingleton());
public static LazySingleton Instance {
get { return lazy.Value; }
}
private LazySingleton() {
Console.WriteLine("Lazy Singleton instance created");
}
public void DisplayMessage() {
Console.WriteLine("Lazy Singleton is working!");
}
}
class Program {
static void Main() {
Console.WriteLine("Before accessing singleton");
LazySingleton instance1 = LazySingleton.Instance;
instance1.DisplayMessage();
LazySingleton instance2 = LazySingleton.Instance;
instance2.DisplayMessage();
Console.WriteLine("Same instance? " + ReferenceEquals(instance1, instance2));
}
}
The output of the above code is −
Before accessing singleton Lazy Singleton instance created Lazy Singleton is working! Lazy Singleton is working! Same instance? True
Comparison of Singleton Implementations
| Implementation | Thread Safety | Performance | Complexity |
|---|---|---|---|
| Basic Singleton | Not thread-safe | Fast | Simple |
| Lock-based Singleton | Thread-safe | Slower due to locking | Moderate |
| Lazy<T> Singleton | Thread-safe | Good performance | Simple |
Common Use Cases
Database connections − Managing a single connection pool
Configuration settings − Loading application settings once
Logging − Single logger instance across the application
Caching − Shared cache accessible throughout the application
Conclusion
The Singleton design pattern ensures only one instance of a class exists throughout the application. Use the Lazy<T> approach for thread-safe, high-performance singleton implementation. The pattern is ideal for managing shared resources like database connections, configuration settings, and logging systems.
