2010-05-27 15 views
11

La salida del siguiente programa es:El constructor estático se puede ejecutar después del constructor no estático. ¿Es esto un error del compilador?

Non-Static 
Static 
Non-Static 

Es esto un error del compilador? Que esperaba:

Static 
Non-Static 
Non-Static 

porque pensé que el constructor estático se llama SIEMPRE antes de que el constructor no estático.

Probé esto con Visual Studio 2010 utilizando .net 3.5 y .net 4.0.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace StaticConstructorBug 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var mc = new MyClass(); 

      Console.ReadKey(); 
     } 
    } 

    public class MyClass 
    { 
     public MyClass() 
     { 
      Console.WriteLine("Non-static"); 
     } 

     static MyClass() 
     { 
      Console.WriteLine("Static"); 
     } 

     public static MyClass aVar = new MyClass(); 
    } 
} 
+0

¿Puede explicar por qué espera que? Porque eso no es lo que la especificación dice esperar. –

Respuesta

11

Ver ECMA 334 §17.4.5.1:

17.4.5.1 campo estático inicialización

campo estático inicializadores de variables de una declaración de clase corresponden a una secuencia de tareas que son ejecutado en el orden textual en el que aparecen en la declaración de clase. Si existe un constructor estático (§17.11) en la clase, la ejecución de los inicializadores de campo estáticos se produce inmediatamente antes de ejecutar el constructor estático . De lo contrario, los inicializadores de campo estático se ejecutan en un tiempo dependiente de la implementación antes de la primera utilización de un campo estático de esa clase

Específicamente: "ejecución de los inicializadores de campo estático se produce inmediatamente antes de ejecutar ese constructor estático ".

Su static MyClass aVar debe inicializarse antes de que se ejecute su constructor estático (o, al menos, debe aparecer de esa manera). Sin ese miembro estático, el constructor estático debería llamarse antes que cualquier constructor no estático.

Si aún desea un singleton MyClass, puede ponerlo en una clase contenedor y consultarlo usando eso, p. Ej.:

public static class MyClassSingleton 
{ 
    public static MyClass aVar = new MyClass(); 
} 
1

Este public static MyClass aVar = new MyClass(); es parte de su constructor estático. Si se mira con reflector verá lo siguiente:

static MyClass() 
{ 
    aVar = new Program.MyClass(); 
    Console.WriteLine("Static"); 
} 

Por lo que su resultado debería ser obvio ahora.

0

De MSDN Link:

Un constructor estático se llama automáticamente para inicializar la clase antes de la primera instancia se crea o algún miembro estáticas están referenciadas.

Mi Supongo que esto se debe a la instanciación estática de la instancia en la última línea, pero de acuerdo con MSDN, el constructor estático debe ocurrir antes de que se llame a la primera instancia.

+0

yeah- por lo que el constructor estático se llama, inicializa el miembro de datos (construido con el constructor normal), entonces el control pasa de nuevo en el constructor estático definido por el usuario, donde se imprime la línea. – Puppy

5

Es causado por la línea public static MyClass aVar = new MyClass();.

De hecho, el aVar = new MyClass(); se precederá al contrstructor estática. Por lo que su constructor estático:

static MyClass() { 
    Console.WriteLine("Static"); 
} 

se cambia a:

static MyClass() { 
    aVar = new MyClass(); // this will run instance contstructor and prints "Non-Static" 
    Console.WriteLine("Static"); 
} 
Cuestiones relacionadas