2010-06-28 12 views
7

Questa implementazione singleton è corretta e thread-safe?L'implementazione di Singleton è corretta e thread-safe?

class Class 
{ 
    public static readonly Class Instance; 

    static Class() 
    { 
     Instance = new Class(); 
    } 

    private Class() {} 
} 
+1

Il costruttore non risponde all'infinito? –

+1

@Robert, no la dichiarazione 'static Class()' è per il costruttore statico che viene chiamato solo una volta. La chiamata a 'new Class()' raggiunge il costruttore di istanze 'Private Class()'. –

+0

Nota, c'è la chiamata di instance ctor all'interno del ctor statico (inizializzatore di classe). – Andreas

risposta

12

Tecnicamente, la versione dovrebbe funzionare. Tuttavia, non consiglierei di esporre un campo pubblico all'interno della tua classe Singleton e preferisco usare una proprietà (solo con getter). Ciò aiuterà la tua API a prova di futuro se hai bisogno di apportare modifiche in seguito. Raccomando anche di sigillare qualsiasi implementazione singleton, poiché la sottoclasse di una classe singleton è quasi sempre una cattiva idea e problematica.

vorrei, personalmente, utilizzare il seguente in C#, se siete destinati a un .NET 3.5 o precedente:

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

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

    static Singleton() { } 
    private Singleton() { } 
} 

Se stai usando .NET 4, si può fare questo ancora più facile per te via Lazy<T>:

public sealed class Singleton 
{ 
    private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton()); 
    private Singleton() {} 
    public static Singleton Instance { get { return instance.Value; } } 
} 

la versione .NET 4 ha anche il vantaggio di essere completamente pigri - anche se la classe Singleton ha altri metodi statici che vengono utilizzati prima l'accesso della proprietà "istanza". Puoi anche fare una versione .NET 3.5 completamente pigra, usando una classe privata e annidata. Jon Skeet demonstrated this on his blog.

+0

Mi piace particolarmente la soluzione Lazy . – Andreas

+0

@Andreas: Anche a me - è anche più "pigro" - dal momento che l'accesso a un metodo statico sulla classe non causa istanziazione - solo la proprietà "Istanza". –

+0

+1 per 'Pigro ' –

2

Sì. Farei anche la classe 'sealed' per evitare qualsiasi confusione futura.

1

Si dovrebbe fare l'inizializzazione nella dichiarazione delle variabili:

public static readonly Class Instance = new Class(); 
+1

Perché? ........... –

+0

Ritarda la costruzione dell'istanza fino al primo riferimento, che può fare la differenza. Inoltre per me è una lettura più pulita. – Joe

+0

@Joe: NON ritarda la costruzione fino al primo riferimento. In effetti, è necessario lasciare il costruttore statico in posizione o la classe verrà contrassegnata primafieldfield, il che potrebbe effettivamente causarne l'istanziazione anche prima (sebbene io preferisca usare anche il costruttore inline). –