Back to: Design Patterns in C# With Real-Time Examples
Why is Singleton Class Sealed in C#?
In this article, I am going to discuss Why Singleton Class Sealed in C# with Examples. Please read our previous article where we discussed the Singleton Design Pattern in C# with Examples. At the end of this article, you will understand why we need to use the sealed keyword in the Singleton class as we already have a private constructor within the class which will restrict the class for further inheritance.
Why Singleton Design Pattern?
As we already discussed we need to use the Singleton Design Pattern in C# when we need to ensure that only one instance of a particular class is available at any given point of time for the entire application.
Why Singleton Class is Sealed in C#?
Let us understand Why the Singleton Class is Sealed in C# with an example. First, create the Singleton class without using the sealed keyword. Then create another class with the name DerivedSingleton and Inherit the DerivedSingleton from the singleton class as shown below.
using System; namespace SingletonDemo { public class Singleton { //This variable value will be increment by 1 each time the object of the class is created private static int Counter = 0; //This variable is going to store the Singleton Instance private static Singleton Instance = null; //The following Static Method is going to return the Singleton Instance public static Singleton GetInstance() { //If the variable instance is null, then create the Singleton instance //else return the already created singleton instance //This version is not thread-safe if (Instance == null) { Instance = new Singleton(); } //Return the Singleton Instance return Instance; } //Constructor is Private means, from outside the class we cannot create an instance of this class private Singleton() { //Each Time the Constructor is called, increment the Counter value by 1 Counter++; Console.WriteLine("Counter Value " + Counter.ToString()); } //The following can be accessed from outside of the class by using the Singleton Instance public void PrintDetails(string message) { Console.WriteLine(message); } } public class DerivedSingleton : Singleton { } }
At the moment, you will get the following compilation error. Error CS0122 ‘Singleton.Singleton()’ is inaccessible due to its protection level
The above error is because of the private constructor that we have in the Singleton class. Now you might be thinking that as we have a private constructor within the class, it is not possible to derive this class, then why do we need to apply the sealed keyword to the Singleton class?
Let’s move the DerivedSingleton class inside the Singleton class. When we move the DerivedSingleton class within the main Singleton class, then it becomes a nested class or you can say a child class of the main Singleton class as shown below.
using System; namespace SingletonDemo { public class Singleton { //This variable value will be increment by 1 each time the object of the class is created private static int Counter = 0; //This variable is going to store the Singleton Instance private static Singleton Instance = null; //The following Static Method is going to return the Singleton Instance public static Singleton GetInstance() { //If the variable instance is null, then create the Singleton instance //else return the already created singleton instance //This version is not thread-safe if (Instance == null) { Instance = new Singleton(); } //Return the Singleton Instance return Instance; } //Constructor is Private means, from outside the class we cannot create an instance of this class //But within the class, we can create an instance private Singleton() { //Each Time the Constructor is called, increment the Counter value by 1 Counter++; Console.WriteLine("Counter Value " + Counter.ToString()); } //The following can be accessed from outside of the class by using the Singleton Instance public void PrintDetails(string message) { Console.WriteLine(message); } //Creating Nested Derived Class inheriting from Singleton Class public class DerivedSingleton : Singleton { } } }
What is a Nested Class in C#?
Whenever we defined a class within another class in C# then the inner class is called a nested class or child class. Now if we compile the program then we will not get any errors.
Let us modify the main method of the program class to access the nested class as shown below.
using System; namespace SingletonDemo { class Program { static void Main(string[] args) { //Call the GetInstance static method to get the Singleton Instance Singleton fromTeachaer = Singleton.GetInstance(); fromTeachaer.PrintDetails("From Teacher"); //Call the GetInstance static method to get the Singleton Instance Singleton fromStudent = Singleton.GetInstance(); fromStudent.PrintDetails("From Student"); //Instantiating singleton from a Derived class. //This violates Singleton Pattern Pattern. Singleton.DerivedSingleton derivedObj = new Singleton.DerivedSingleton(); derivedObj.PrintDetails("From Derived"); Console.ReadLine(); } } }
Now if you run the application then you will see the following output.
The above output clearly shows that the counter value has incremented to 2 which proves that the private constructor executed twice and hence it creates multiple instances of the singleton class. So, by removing the sealed keyword we can inherit the singleton class, and also possible to create multiple objects of the singleton class. This violates singleton design principles. Let’s make the Singleton class as sealed as shown below and then compiled the program and see what happens.
using System; namespace SingletonDemo { public sealed class Singleton { //This variable value will be increment by 1 each time the object of the class is created private static int Counter = 0; //This variable is going to store the Singleton Instance private static Singleton Instance = null; //The following Static Method is going to return the Singleton Instance public static Singleton GetInstance() { //If the variable instance is null, then create the Singleton instance //else return the already created singleton instance //This version is not thread-safe if (Instance == null) { Instance = new Singleton(); } //Return the Singleton Instance return Instance; } //Constructor is Private means, from outside the class we cannot create an instance of this class //But within the class, we can create an instance private Singleton() { //Each Time the Constructor is called, increment the Counter value by 1 Counter++; Console.WriteLine("Counter Value " + Counter.ToString()); } //The following can be accessed from outside of the class by using the Singleton Instance public void PrintDetails(string message) { Console.WriteLine(message); } //Creating Nested Derived Class inheriting from Singleton Class public class DerivedSingleton : Singleton { } } }
Now we got an error when compiling the program saying that we cannot derive a sealed class. So from this point, we conclude that the private constructor in C# will help us only prevent any external instantiations of the class and the sealed keyword will prevent the class inheritances.
The above Singleton implementation is not thread-safe. The way we implement the Singleton class allows two different threads at the same time to be evaluated the condition if (instance == null) and found it to be true and they both create the instances, which violates the singleton design pattern.
In the next article, I am going to discuss How to Handle Thread Safety in Singleton Class as the current version of singleton implementation can create multiple instances of the singleton class in multi-threaded environments. Here, in this article, I try to explain Why the Singleton Class Sealed in C# with Examples. I hope this article will help you to understand Why the Singleton Class is Sealed in C# with Examples.
Thank you. Well explained.
Thank you, excellent explanation!
Awesome
awesome tutorial, thank you
Nice, Thank you.
Well explained. Thanks team dotnettutorials and to the author of this course.