I watched another video in a series on C# that’s been making its round on the news sites I read. This time the subject was private constructors. It made two points at the beginning with which I disagree.
1. A class with a private constructor can not be inherited.
This compiles just fine.
public class A
{
private A()
{
}
public class B : A
{
}
}
The private keyword will make that particular constructor inaccessible. If it’s a nested class, the outer class’ private members are accessible, making this valid.
Okay, that’s atypical. However, this is valid as well.
public class A
{
private A()
{
}
public A(int val)
{
}
}
public class B : A
{
public B():base(default(int))
{
}
}
The rule should be worded: 1. A class can only be inherited if it has an accessible constructor.
2. We can not create an object of the class which has a private constructor.
This suffers from the same issue as above. I would word it as: 2. A class cannot be instantiated unless it has an accessible constructor. This rule is ignoring factories. However, the factory is doing the instantiating.
Near the end of the video, it added a new line to the slide.
3. Many times we do not want to create instances of certain classes like utility, common routine classes.
The video then gives the following example if when to use it.
public class class1
{
private class1()
{
}
public static string getData()
{
return "Hello";
}
}
I know examples can be simplistic, but with the wording of the third note, I want to warn everyone against doing this. As of C# 2.0, static classes have been available. If you’re going to make a utility class that should never be instantiated, do this instead (plus, drop the Java-style naming convention):
public static class Class1
{
public static string GetData()
{
return "Hello";
}
}
There are interesting design patterns that make use of an inaccessible constructor so one is forced to use a factory method. Perhaps the most infamous is the Singleton pattern, which ensures only one instance of a class is available.
public class Singleton
{
private static Singleton instance;
public static Singleton Instance
{
get
{
return instance = instance ?? new Singleton();
}
}
private Singleton()
{
}
}
Accessing this implementation of singleton is done via the static property… calling Singleton.Instance. You would use this instead of a static class when an instance is required for a task such as serialization.
Both utility classes and singletons are often considered antipatterns. Helper classes (like utility classes, but intended to aid a non-extendable class) can make your code cleaner with extension methods.
The video poses the following question: “What is the use of a private constructor.” I would answer differently than the video.
1. A class can only be inherited if it has an accessible constructor.
2. A class cannot be instantiated unless it has an accessible constructor.
3. Private constructors enable design patterns such as Singleton.