Il blog di TixXio Un blog impossibile o privo di significato

9gen/100

C# Singleton

In questi ultimi mesi ho avuto la necessità di trovare un'implementazione del pattern singleton in C# che fosse un buon compromesso tra scarnezza del codice e laziness nella creazione dell'istanza.

Dopo un pò di ricerche ed esperimenti ho scelto la soluzione di seguito:

public sealed class MyObject
{

    // Dichiaro un costruttore statico per far si che il compilatore c# non
    // consideri il tipo come beforefieldinit
    static MyObject() { }
    MyObject() { }

    // Istanza privata dell'oggetto
    private static readonly MyObject _instance = new MyObject();

    // Proprietà pubblica che espone l'istanza all'esterno
    public static MyObject Instance
    {
        get { return _instance;  }
    }
}

Il costruttore statico garantisce che l'implementazione sia thread-safe: in questo modo l'inizializzazione dell'istanza _instance viene eseguita una sola volta per esecuzione. Inoltre per la presenza dello stesso costruttore statico la classe non viene marcata con il flag beforefieldinit dal compilatore, l'oggetto _instance viene quindi istanziato solamente alla primo accesso ad una proprietà statica di MyObject.

Se avete la necessità di un'implementazione thread safe potete modificare la proprietà pubblica come segue:

public sealed class MyObject
{
    static MyObject() { }
    MyObject() { }

    private static readonly MyObject _instance = null;

    public static MyObject Instance
    {
        get
        {
            lock(_instance)
            {
                if (_instance == null) _instance = new MyObject();
                return _instance;
            }
        }
    }
}

Cosa ne pensate di queste soluzioni? Avete individuato dei problemi a cui non ho fatto caso? Aspetto i vostri suggerimenti a riguardo nei commenti :)