The NAG Constructor Pattern |
This topic contains an article describing a design pattern first introduced in AsyncInit.
This topic contains the following sections:
A base class may occasionally require subclasses to limit the visibility of their constructor(s). Common example:
abstract class Singleton<T> where T : Singleton<T> { public static readonly T Instance; static Singleton() { Instance = new System.Lazy<T>(CreateInstance).Value; } private static T CreateInstance() { return (T)System.Activator.CreateInstance(typeof(T), true); } }
The true bit instructs Activator to look for a non-public constructor, but not to require it. This means that a subclass could easily forgo the private constructor (by e.g. declaring no constructor at all), which would defeat the whole purpose of it trying to be a singleton.
Ideally, we would like to enforce this at compilation time. C# affords us the new constraint:
abstract class NotSingleton<T> where T : NotSingleton<T>, new() { //... }
abstract class Singleton<T> where T : Singleton<T>, ~new() { //... }
AsyncInitBase<T>, a class not too dissimilar from the above Singleton<T>, contains the following code:
/// <summary> /// Deriving types should define a private parameterless constructor. /// </summary> /// <param name="dummy">Dummy parameter (safe to pass <c>null</c>).</param> protected AsyncInitBase(object dummy) { }
Its goal is to enforce implementors to define a constructor of their own, with the hope that it indeed be a private one.