2012-03-16 18 views
5

Estaba pasando por la siguiente implementación de Singleton mencionada here. Entiendo que los constructores estáticos se ejecuten antes de la primera llamada al método estático o antes de que el objeto te sea instanciado, pero no entendí su uso aquí (incluso a partir de los comentarios). ¿Alguien podría ayudarme a entenderlo?Implementación Singleton con el constructor estático vacío

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; 
     } 
    } 
} 
+2

Se explica en los puntos debajo de él, específicamente: 'La pereza de los inicializadores de tipo solo está garantizada por .NET cuando el tipo no está marcado con una bandera especial llamada 'beforefieldinit'. Desafortunadamente, el compilador de C# (como se proporciona en el tiempo de ejecución de .NET 1.1, al menos) marca todos los tipos que no tienen un constructor estático (es decir, un bloque que parece un constructor pero está marcado estático) como 'beforefieldinit'. , quiere que el 'nuevo Singleton()' se construya lo más tarde posible (de forma perezosa), y la única forma de hacer que el compilador de C# lo haga es proporcionar un constructor estático vacío. – porges

+0

Perdona mi ignorancia. Qué es "la pereza de los inicializadores de tipo". Es la inicialización a la primera solicitud? – Nemo

+0

Exactamente. Solo está garantizado en esa situación, de lo contrario, el tiempo de ejecución puede ejecutar los inicializadores de tipo siempre que lo desee, por ejemplo, tan pronto como se cargue el tipo. Para una explicación más larga, vea el enlace en la respuesta de Jay. – porges

Respuesta

7

El constructor estático no está allí con el fin de que se debería llamar antes o después de cualquier otra cosa, sólo como una manera de hacer que el compilador no establecer el indicador beforefieldinit.

Más información sobre esto aquí: What does beforefieldinit flag do?

La razón fundamental es lograr una medida de la pereza en la inicialización del objeto Singleton. Si se establece beforefieldinit (porque no se define un constructor estático), la ejecución de un método que condicionalmente hace referencia a Singleton.Instance es probable que inicialice el objeto singleton, , incluso si la condición no se cumple y esa llamada nunca se realiza.

public void Foo() 
{ 
    if (false) 
    { 
     var bar = Singleton.Instance.SomeMethod(); 
    } 
} 

Por otro lado, si beforefieldinit no se establece (porque un constructor estático se define - incluso una vacía), a continuación, ejecutar el mismo método sólo hará que la instancia singleton a ser inicializado si la condición está satisfecho y esa llamada es realmente hecho.

Ese artículo se enciende para señalar que esta implementación particular no es plenamente perezosos porque llamar a cualquier otra miembro estático que se define en la clase Singleton también causará Instance que ser inicializado.

Cuestiones relacionadas