2010-06-28 9 views
7

¿Es esta implementación singleton correcta y segura para subprocesos?¿Es esta implementación de Singleton correcta y segura para subprocesos?

class Class 
{ 
    public static readonly Class Instance; 

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

    private Class() {} 
} 
+1

¿El constructor no se repetirá infinitamente? –

+1

@Robert, no, la declaración 'static Class()' es para el constructor estático al que solo se llama una vez. La llamada a 'new Class()' golpea al 'constructor de instancias privado Class()'. –

+0

Nota, hay una llamada a instancia de ctor dentro del ctor estático (inicializador de clase). – Andreas

Respuesta

12

Técnicamente, su versión debería funcionar. Sin embargo, no recomendaría exponer un campo público dentro de su clase Singleton, y prefiero usar una propiedad (solo con un getter). Esto ayudará a proteger su API a futuro si necesita realizar cambios más adelante. También recomiendo sellar cualquier implementación singleton, ya que la subclase de una clase singleton es casi siempre una mala idea y problemática.

lo haría, personalmente, utilice el siguiente en C#, si está destinada a una audiencia .NET 3.5 o anterior:

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

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

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

Si está utilizando .NET 4, usted puede hacer esto aún más fácil para usted a través de 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 versión .NET 4 también tiene la ventaja de ser totalmente vago - incluso si su clase Singleton tiene otros métodos estáticos que son utilizados con anterioridad al acceso de la propiedad "Instancia". También puede hacer una versión .NET 3.5 totalmente vacía, utilizando una clase anidada privada. Jon Skeet demonstrated this on his blog.

+0

Me gusta especialmente la solución Lazy . – Andreas

+0

@Andreas: Yo también, también es más "flojo", ya que acceder a un método estático en la clase no causará creación de instancias, solo la propiedad "Instancia". –

+0

+1 por 'Lazy ' –

2

Sí. También haría la clase 'sealed' para evitar confusiones futuras.

1

que debe hacer la inicialización en la declaración de variables:

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

¿Por qué? ........... –

+0

Retrasa la construcción de la instancia hasta la primera referencia de la misma, lo que puede hacer una diferencia. Además, para mí es una lectura más limpia. – Joe

+0

@Joe: NO retrasa la construcción hasta la primera referencia. De hecho, debes dejar el constructor estático en su lugar o la clase se marcará antes del inicio del campo, lo que en realidad puede hacer que se cree una instancia incluso antes (aunque prefiero usar el constructor en línea también). –

Cuestiones relacionadas