2010-11-10 24 views
14

Queridos todos, la pregunta como esta ha sido already asked, pero entre las respuestas no había explicación del problema que veo.¿Constructor estático llamado después del constructor de la instancia?

El problema: la C# Programming Guide dice:

Un constructor estático se utiliza para inicializar los datos estáticos, o para realizar una acción particular que debe realizarse una sola vez. Se llama automáticamente antes de que se cree la primera instancia o se hace referencia a cualquier miembro estático.

En particular, se llama al constructor estático antes de crear cualquier instancia de una clase. (Esto no asegura que el constructor estático termina antes de la creación de la instancia, pero esto es otra historia.)

Consideremos el código de ejemplo:

using System; 

public class Test 
{ 
    static public Test test = new Test(); 
    static Test() 
    { 
     Console.WriteLine("static Test()"); 
    } 
    public Test() 
    { 
     Console.WriteLine("new Test()"); 
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     Console.WriteLine("Main() started"); 
     Console.WriteLine("Test.test = " + Test.test); 
     Console.WriteLine("Main() finished"); 
    } 
} 

Genera:

main() comenzó
nueva prueba()
prueba estática()
Test.test = Prueba
main() terminada

Así podemos ver que los acabados ejemplo constructor (y por lo tanto se crea una instancia) antes el constructor estático comienza. ¿Esto no contradice a la Guía? ¿Tal vez la inicialización de campos estáticos se considera una parte implícita del constructor estático?

+1

¿Por qué no crear una instancia fuera de la clase en lugar de asignar una instancia a una propiedad estática, y luego verificar el orden? Esto parece una forma original de probarlo. – mway

+0

¿No es porque estás instanciando un miembro 'estático' ...? – rsenna

+0

@mway: puede funcionar de otra manera, pero me gustaría entender qué sucede exactamente en este caso. – Vlad

Respuesta

23

Inicializadores en línea para los campos static que se ejecutan antes del constructor static explícito.

El compilador transforma su clase en algo como esto:

public class Test { 
    .cctor { //Class constructor 
     Test.test = new Test();    //Inline field initializer 
     Console.WriteLine("static Test()"); //Explicit static ctor 
    } 
    .ctor { ... } //Instance constructor 
} 

Tenga en cuenta que esto es independiente del orden de declaración.

citar el spec:

campo estático inicializadores de variables de una clase corresponden a una secuencia de tareas que se ejecutan en el orden textual en el que aparecen en la declaración de clase . Si un estática constructor (Section 10.11) existe en la clase, la ejecución de los inicializadores de campo estático se produce inmediatamente antes de ejecutar que estática constructor.

+1

Sí, esto está garantizado por http://msdn.microsoft.com/en-us/library/79b3xss3.aspx: "Los miembros estáticos se inicializan antes de que se acceda al miembro estático por primera vez y antes del constructor estático, si existe es uno, se llama ". ¿Pero esto no contradice la primera cita de la pregunta? – Vlad

+1

+1 Sí, lo tienes clavado. – rsenna

+0

@Vlad: si el ctor estático crea una instancia de la clase, no terminará hasta que cree una instancia de la clase. – SLaks

Cuestiones relacionadas