Unser Singleton Pattern soll folgende Anforderungen erfüllen:

  • Lazy: Die Instanz wird erst erstellt wenn das erste Mal darauf zugegriffen wird.
  • Threadsafe: Auch wenn mehrere Threads gleichzeitig zum ersten Mal auf die Singleton Instanz zugreifen soll sichergestellt sein, dass der Konstruktor nur einmal aufgerufen wird.
  • ohne unnötige Locks: Ein lock()-Block ist eine relativ "teure" Operation, sie soll deshalb möglichst nicht bei jedem Zugriff auf die Singleton Instanz aufgerufen werden.

Bis und mit .NET 3.5: Der statische private Konstruktor stellt sicher, dass die Instanz nicht schon bei der Initialisierung der Klasse, sondern erst beim ersten Zugriff auf die Variable 'instance' erstellt wird.

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

.NET 4.0 und neuer: Der leere statische Konstruktor ist nicht mehr notwendig, die Instanz wird immer erst beim ersten Zugriff auf 'instance' erstellt.

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get; } = new Singleton();
}

Im privaten Konstruktor kann eigener Code eingefügt werden der die Singleton Instanz initialisiert.

Die Threadsicherheit wird bei statischen Variablen durch das .NET Framework garantiert. Wichtig: Dieses Pattern funktioniert so nur in .NET, in Java wäre die Threadsicherheit z.B. nicht gegeben!