I know other threads exist regarding this question but I couldn't find satisfactory answer for this. Why singleton class needs to be sealed in C# ? (To clarify my question)Does making it sealed really help it achieving goal of singleton (only one instance) ?
I have added more clarification about what I am wanting to know and trying to find reason for, hope readers understand what I am trying to discuss.
I am talking about MSDN article's thread safe solution : https://msdn.microsoft.com/en-us/library/ff650316.aspx.
In this article first they give solution which is not thread safe, then they give another solution using static initialization to make it thread safe and in that solution they make class: sealed
As per MSDN's explanation -- The class is marked sealed to prevent derivation, which could add instances. For a discussion of the pros and cons of marking a class sealed, see [Sells03].
When I tried to figure why they used Sealed in static initialization approach, only thing I could figure is: as they wanted to prevent additional instantiation they made it sealed (this only prevents instantiation done through derivation, nested sub class derivation could create additional instances but by using Sealed it doesn't prevent nested class from creating additional instances.) to achieve goal of singleton. If using sealed doesn't prevent additional instantiation through other ways then why use it ?
Below is the MSDN's thread safe solution:
public sealed class Singleton { private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance { get { return instance; } } }
My question is does MSDN's thread safe solution achieve goal of singleton by making it sealed? They made class sealed to prevent instantiation through derivation but that doesn't stop instantiation done through other ways. See my example below:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return instance;
}
}
public class nestedSingleton
{
public nestedSingleton()
{
Singleton moreThanOneObject = new Singleton();
}
}
}
Simply put: if anyone can derive from it, there can be multiple instances. So you definitely need some way of preventing arbitrary derivation.
Now you can simply rely on a private constructor to prevent subclassing instead (and you need the private constructor anyway), but the only reason for making a Singleton
class unsealed would be if you wanted a nested type to be the implementation, e.g.
public class Singleton
{
public static Singleton Instance { get; }
= (DateTime.Now.Seconds & 1) == 0
? (Singleton) new EvenSingleton() : new OddSingleton();
private Singleton() {}
private class OddSingleton : Singleton {}
private class EvenSingleton : Singleton {}
}
This is properly a singleton - but it's a pretty unusual situation. It's vastly more common not to need a nested type to be the implementation, at which point it's clearer IMO to seal the singleton to make it clearer that you don't intend there to be any subclasses.
Basically it's communication as much as anything - a sealed
class clearly prohibits derivation, whereas just having the private constructor (but no nested types) makes it more implicit. I think being explicit is clearer.
(Also, in earlier versions of C#, there are some bizarre ways you can get subclasses to compile with mutually recursive constructor calls so you never end up with a base constructor initializer. This has now been fixed, fortunately.)
To respond to a question addition:
Sealed keyword doesnt even make sense in this case if MSDN added it to prevent creating more instances of singleton by Nested sub classes.
In the example you've given, the nested class isn't a subclass. It looks like this:
public class nestedSingleton
whereas a nested subclass would look like this:
public class nestedSingleton : Singleton
(except ideally following .NET naming conventions).
See more on this question at Stackoverflow