2010-05-27 13 views
11

L'output del seguente programma è:Il costruttore statico può essere eseguito dopo il costruttore non statico. È un bug del compilatore?

Non-Static 
Static 
Non-Static 

Si tratta di un bug del compilatore? Mi aspettavo:

Static 
Non-Static 
Non-Static 

perché ho pensato che il costruttore statico è sempre stato chiamato prima il costruttore non statico.

L'ho provato con Visual Studio 2010 utilizzando sia .net 3.5 che .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

Può spiegare perché vi aspettavate che? Perché non è quello che le specifiche dicono di aspettarsi. –

risposta

11

Vedi ECMA 334 §17.4.5.1:

17.4.5.1 campo statico inizializzazione

del campo statico initializers variabili di dichiarazione di una classe corrisponde ad una sequenza di compiti che sono eseguito nel ordine testuale in cui appaiono nella dichiarazione di classe. Se nella classe è presente un costruttore statico (§17.11) , l'esecuzione degli inizializzatori di campo statici si verifica immediatamente prima dell'esecuzione di tale costruttore statico . Altrimenti, i inizializzatori campo statico sono eseguiti in un tempo dipendente dall'implementazione prima del primo uso di una statica campo di quella classe

particolare: "esecuzione dei inizializzatori campo statico avviene immediatamente prima dell'esecuzione quel costruttore statico ".

Il tuo static MyClass aVar deve essere inizializzato prima dell'esecuzione del costruttore statico (o, almeno, deve apparire in questo modo). Senza quel membro statico, il costruttore statico dovrebbe essere chiamato prima di qualsiasi costrutto non statico.

Se si desidera ancora un singleton MyClass, è possibile inserirlo in una classe contenitore e fare riferimento ad esso utilizzando tale, ad es.:

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

Questo public static MyClass aVar = new MyClass(); è parte del costruttore statico. Se lo guardi con il riflettore, vedrai quanto segue:

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

Quindi il risultato dovrebbe essere ovvio ora.

0

Da MSDN Link:

Un costruttore statico viene chiamato automaticamente per inizializzare la classe prima della prima istanza viene creata o qualsiasi membri statici sono raffrontate.

My Guess questo è dovuto all'istanza statica dell'istanza sull'ultima riga, ma in base a MSDN il costruttore statico dovrebbe accadere prima che venga chiamata la prima istanza.

+0

Sì, viene chiamato il costruttore statico, inizializza il membro dati (costruito con il normale costruttore), quindi il controllo ritorna nel costruttore statico definito dall'utente, dove stampa la linea. – Puppy

5

È causato dalla linea public static MyClass aVar = new MyClass();.

Infatti lo aVar = new MyClass(); è anteposto al controstore statico. Così il vostro costruttore statico:

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

viene modificato in:

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