Di seguito sono due diversi modi per inizializzare i campi statici in lettura. C'è una differenza tra i due approcci? Se sì, quando si dovrebbe preferire l'altro?inizializzatore di campo statico readon vs inizializzazione del costruttore statico
risposta
C'è una sottile differenza tra questi due, che può essere visto nel codice IL - mettere un costruttore esplicito statico dice al compilatore C# di non contrassegnare il tipo come beforefieldinit. Il beforefieldinit ha effetto quando viene eseguito l'inizializzatore del tipo e la conoscenza di ciò è utile quando si scrive lazy singletons in C#, ad esempio.
In breve la differenza è questa:
.class private auto ansi beforefieldinit A
.class private auto ansi B
In tutti gli altri aspetti che sono gli stessi. Uscita dal riflettore:
Classe A:
.class private auto ansi beforefieldinit A
extends [mscorlib]System.Object
{
.method private hidebysig specialname rtspecialname static void .cctor() cil managed
{
.maxstack 8
L_0000: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection> WebConfigurationManager::ConnectionStrings
L_0005: ldstr "SomeConnection"
L_000a: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection>::get_Item(!0)
L_000f: ldfld string Connection::ConnectionString
L_0014: stsfld string A::connectionString
L_0019: ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: ret
}
.field private static initonly string connectionString
}
Classe B:
.class private auto ansi B
extends [mscorlib]System.Object
{
.method private hidebysig specialname rtspecialname static void .cctor() cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection> WebConfigurationManager::ConnectionStrings
L_0006: ldstr "SomeConnection"
L_000b: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection>::get_Item(!0)
L_0010: ldfld string Connection::ConnectionString
L_0015: stsfld string B::connectionString
L_001a: ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: ret
}
.field private static initonly string connectionString
}
Essi sono essenzialmente la stessa, ma se vi capita di avere sia un incarico di sola lettura a un campo statico e un tipo di costruttore statico, l'assegnazione di sola lettura si verifica per primo.
Il beforefieldinit attributo indica l'inizializzazione avviene.
In caso di inizializzazione di un costruttore statico esplicito, l'inizializzazione del membro statico avviene nel momento in cui si accede al tipo. Nell'esempio fornito in caso di classe A, l'inizializzazione avverrà solo quando viene fatto riferimento a connectionString, mentre in caso di inizializzazione di classe B si verificherà la prima volta che la classe di tipo B viene indirizzata, non necessariamente l'accesso a connectionString.
Solo C# (.NET 4.0) ci fornisce il controllo su come i membri statici possono essere inizializzati. Con VB.NET è possibile solo il metodo non beforefieldinit mentre con C++/CLI è possibile solo il meccanismo beforefieldinit.
- 1. Inizializzazione del campo statico Java
- 2. C'è un costruttore statico o un inizializzatore statico in Python?
- 3. Tipo inizializzatore (costruttore statico) gestione delle eccezioni
- 4. Inizializzazione del vettore statico
- 5. Inizializzatore membro non statico da un altro non statico
- 6. Inizializzazione del campo statico in classe template in C++
- 7. Impossibile riferirsi al campo enum statico all'interno di un inizializzatore?
- 8. Ordine di inizializzazione statico C++
- 9. Get di campo statico
- 10. Costruttore pubblico e costruttore statico
- 11. Costruttore statico per l'intero assieme
- 12. Eccezione nel costruttore statico
- 13. C# statico generico costruttore
- 14. Costruttore statico in VB.NET
- 15. Accesso principali argomenti da un inizializzatore statico
- 16. statico inizializzazione su OpenCV Android
- 17. Blocco statico rispetto al metodo statico - inizializzazione dei campi statici
- 18. Il costruttore statico può essere eseguito dopo il costruttore non statico. È un bug del compilatore?
- 19. Inizializzatore statico su una classe interna?
- 20. Come funziona un costruttore statico?
- 21. costruttore Perché enum non può accedere campo statico
- 22. Assegnare al campo finale statico del omonimo
- 23. Valore impostato del campo statico privato
- 24. Un inizializzatore di campo non può fare riferimento il campo non statico, metodo o proprietà
- 25. Equivalente costruttore statico in Objective-C?
- 26. Linking: Statico vs dinamico
- 27. Statico vs globale
- 28. C, saltare l'array statico di inizializzazione
- 29. Membro statico fallimento oggetto di inizializzazione
- 30. Inizializzazione dell'array statico di stringhe (C++)?