Abstract base class to force each derived classes to be Singleton

Classes in java or C# are not "first-class". The static part of a class can not be inherited or overridden by subclasses. See this answer for more details. Plus, you don't have a concept of meta-class.

In languages like Smalltalk or Ruby, you can define a new metaclass Singleton which defines a method getInstance. Then you can define ClassA and ClassB be instances of the Singleton metaclass. Then both classes automatically expose a method getInstance which can be used to create instances objectA or objectB. Isn't that cool? Well, in practice you don't use metaclass frequently, and the singleton is actually the only usage of them that makes sense and that I'm aware of.


When you want to enfore compile time checking, this is not possible. With runtime checking you can do this. It's not pretty, but it's possible. Here's an example:

public abstract class Singleton
{
    private static readonly object locker = new object();
    private static HashSet<object> registeredTypes = new HashSet<object>();

    protected Singleton()
    {
        lock (locker)
        {
            if (registeredTypes.Contains(this.GetType()))
            {
                throw new InvalidOperationException(
                    "Only one instance can ever  be registered.");
            }
            registeredTypes.Add(this.GetType());
        }
    }
}

public class Repository : Singleton
{
    public static readonly Repository Instance = new Repository();

    private Repository()
    {
    }
}

that would not work because the singleton needs somwhere a static access and that can not be forced.

for singletonimplemention + examples see: Implementing the Singleton Pattern in C#


Singleton means having private constructors. But you know private members cannot be inherited. In C++ there were templates, so you could create a singleton from a template class. in C#, there aren't templates, so you have to write your own private constructors for every singleton you want.

Tags:

C#

Oop

Ooad