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
Why singleton class is always sealed in C#?
A singleton class is marked as sealed in C# to prevent inheritance and maintain the single instance guarantee that is fundamental to the singleton pattern. The sealed keyword ensures that no other class can inherit from the singleton class, which could potentially create multiple instances and violate the singleton principle.
Why Singleton Classes Must Be Sealed
The singleton pattern ensures only one instance of a class exists throughout the application lifecycle. If a singleton class allows inheritance, derived classes could create their own instances, breaking this fundamental rule. Here are the key reasons −
Prevents Multiple Instances: Derived classes could bypass the singleton's instance control mechanism.
Maintains Pattern Integrity: Inheritance would allow multiple object creation paths, violating singleton principles.
Constructor Control: While constructors aren't inherited, derived classes can define public constructors, making direct instantiation possible.
Problem with Non-Sealed Singleton
Here's an example showing why singleton classes should be sealed −
using System;
public class NonSealedSingleton {
private static NonSealedSingleton instance = null;
private static int counter = 0;
private NonSealedSingleton() {
counter++;
Console.WriteLine("NonSealedSingleton instance created. Counter: " + counter);
}
public static NonSealedSingleton GetInstance() {
if (instance == null) {
instance = new NonSealedSingleton();
}
return instance;
}
public void PrintMessage(string message) {
Console.WriteLine("NonSealedSingleton: " + message);
}
}
public class DerivedSingleton : NonSealedSingleton {
public DerivedSingleton() {
Console.WriteLine("DerivedSingleton instance created - violating singleton!");
}
}
public class Program {
public static void Main() {
NonSealedSingleton s1 = NonSealedSingleton.GetInstance();
s1.PrintMessage("First instance");
// Problem: We can create multiple instances through inheritance
DerivedSingleton derived = new DerivedSingleton();
Console.WriteLine("Singleton pattern violated!");
}
}
The output of the above code is −
NonSealedSingleton instance created. Counter: 1 NonSealedSingleton: First instance DerivedSingleton instance created - violating singleton! Singleton pattern violated!
Correct Sealed Singleton Implementation
Here's the proper way to implement a sealed singleton class −
using System;
public sealed class Singleton {
private static Singleton instance = null;
private static readonly object lockObject = new object();
private static int counter = 0;
private Singleton() {
counter++;
Console.WriteLine("Singleton instance created. Counter: " + counter);
}
public static Singleton GetInstance() {
if (instance == null) {
lock (lockObject) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
public void PrintMessage(string message) {
Console.WriteLine("Singleton: " + message);
}
}
public class Program {
public static void Main() {
Singleton s1 = Singleton.GetInstance();
s1.PrintMessage("First access");
Singleton s2 = Singleton.GetInstance();
s2.PrintMessage("Second access");
Console.WriteLine("Same instance: " + (s1 == s2));
// Compilation error if uncommented:
// public class DerivedSingleton : Singleton { }
}
}
The output of the above code is −
Singleton instance created. Counter: 1 Singleton: First access Singleton: Second access Same instance: True
Benefits of Sealed Singleton
| Benefit | Description |
|---|---|
| Instance Control | Prevents creation of multiple instances through inheritance |
| Pattern Integrity | Maintains the core principle of having only one instance |
| Thread Safety | Easier to implement thread-safe singleton when inheritance is prevented |
| Performance | No virtual method calls, enabling compiler optimizations |
Conclusion
Singleton classes are always sealed in C# to prevent inheritance that could violate the single-instance principle. The sealed keyword ensures that derived classes cannot bypass the singleton's instance control mechanism, maintaining pattern integrity and preventing multiple object creation.
