Quando viene chiamato un costruttore statico in C #?


88

Quando ho una classe contenente un costruttore statico, quel costruttore viene chiamato quando l'assembly contenente la classe viene caricato per la prima volta o quando viene raggiunto il primo riferimento a quella classe?

Risposte:


93

Quando si accede alla classe per la prima volta.

Costruttori statici (Guida per programmatori C #)

Un costruttore statico viene utilizzato per inizializzare i dati statici o per eseguire un'azione particolare che deve essere eseguita una sola volta. Viene chiamato automaticamente prima della creazione della prima istanza o prima di fare riferimento a qualsiasi membro statico.


6
È interessante che dica "prima che venga creata la prima istanza o venga fatto riferimento a qualsiasi membro statico". C'è un certo margine di manovra quando viene effettivamente richiamato.
Tim Barrass

6
@TimBarrass a causa di alcuni altri requisiti di specifica scopre che "prima" è in realtà "immediatamente prima di" - vedi l'articolo di Jon Skeet menzionato nell'obiettivo altra risposta - stackoverflow.com/a/1437372/477420
Alexei Levenkov

A static constructor is used to initialize any static dataNO. Meglio da usare static initializerper inizializzare cose statiche.
Yousha Aleayoub

41

Non è così semplice come ci si potrebbe aspettare nonostante la documentazione diretta. L'articolo di Jon Skeet http://csharpindepth.com/Articles/General/Beforefieldinit.aspx approfondisce questa domanda.

Sommario:

È garantito che il costruttore statico venga eseguito immediatamente prima del primo riferimento a un membro di quella classe: creazione dell'istanza o metodo / proprietà statica della classe.

Si noti che gli inizializzatori statici (se non esiste un costruttore statico) garantiscono l'esecuzione in qualsiasi momento prima del primo riferimento a un campo particolare.


L'articolo citato è ora sul sito di Jon Skeet: csharpindepth.com/Articles/General/Beforefieldinit.aspx
Sudhanshu Mishra

La seguente domanda stackoverflow.com/questions/32525628/… mostra il caso in cui il comportamento "immediato" è abbastanza ovvio.
Alexei Levenkov

1
In realtà ho appena avuto il caso in cui un costruttore statico è stato chiamato proprio prima che il metodo Main di un'applicazione console iniziasse l'esecuzione!
HerpDerpington

19

Il costruttore statico viene chiamato prima di usare qualsiasi cosa nella classe, ma esattamente quando ciò accade dipende dall'implementazione.

È garantito che venga chiamato prima dell'accesso al primo membro statico e prima della creazione della prima istanza. Se la classe non viene mai utilizzata, non è affatto garantito che il costruttore statico venga chiamato.


2
Quando accade non dipende "dall'implementazione" se tale implementazione segue le specifiche ECMA C #: "L'esecuzione di un costruttore statico viene attivata dal primo dei seguenti eventi che si verificano all'interno di un dominio dell'applicazione: [1] Un'istanza del viene creata la classe. [2] Viene fatto riferimento a uno qualsiasi dei membri statici della classe. " (Sezione 17.11, ecma-international.org/publications/standards/Ecma-334.htm )
Luca

1
@Luke: "La tempistica esatta dell'esecuzione del costruttore statico dipende dall'implementazione
Guffa

2
@Guffa: Potrebbe essere l'interpretazione dell'autore dell'articolo, ma non troverai quella formulazione nelle versioni Microsoft o ECMA / ISO delle specifiche C #.
LukeH

1

Nel caso in cui il metodo statico venga chiamato dalla classe genitore, il costruttore statico non verrà chiamato, anche se è esplicitamente specificato. Ecco un esempio b.Il costruttore non viene chiamato se viene chiamato b.methoda ().

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    

1

Sembra che ci sia un problema con i costruttori statici a cui è stata data risposta altrove, ma ci è voluto un po 'per digerire in una semplice spiegazione. Tutti i documenti e le spiegazioni affermano che il costruttore / inizializzatore statico è "garantito" per essere eseguito prima che venga creata un'istanza della prima classe o venga fatto riferimento al primo campo statico. Il gotcha arriva quando si tenta di inserire un singleton statico nella classe che crea un'istanza di se stesso (pollo / uovo). In questo caso il costruttore statico finisce per essere chiamato dopo il costruttore dell'istanza, e nel mio caso il costruttore dell'istanza conteneva codice che si basava su alcuni dati statici.

Costruttore statico chiamato dopo il costruttore di istanze?

Il costruttore statico può essere eseguito dopo il costruttore non statico. È un bug del compilatore?

(la risposta per me era mettere il singleton in una classe separata o inizializzare manualmente i dati statici nel costruttore dell'istanza prima che fosse richiesto)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.