2014-07-24 14 views
13

Ich bin auf ein C# -Verhalten gestoßen, das ich gerne verstehen würde. Betrachten wir eine Klasse wie folgt:C# statisches Feld, Instanzkonstruktor

public class SomeSingleton 
{ 
    public static SomeSingleton Default = new SomeSingleton(); 

    private static int field = 0; 

    private SomeSingleton() 
    { 
     field = 1; 
    } 

    public int GetField() 
    { 
     return field; 
    } 
} 

Jetzt wollen wir nennen GetField() -Methode:

var field = SomeSingleton.Default.GetField(); 

Ich erhalte 0 als ob der Instanzkonstruktor übersprungen wurde. Warum?

Antwort

26

Tauschen Sie einfach die Reihenfolge der field Deklaration vor Default.

So Ihre Linien:

public static SomeSingleton Default = new SomeSingleton(); 
private static int field = 0; 

sein sollte:

private static int field = 0; 
public static SomeSingleton Default = new SomeSingleton(); 

Der Grund Feld Initialisierungsreihenfolge zurückzuführen ist. Zuerst wird Default in Ihrem Code initialisiert, der field Wert von 1 zuweist. Später wird dieses Feld in der Initialisierung 0 zugewiesen. Daher sehen Sie den neusten Wert von 0 und nicht 1.

See: 10.4.5.1 Static field initialization

Die statische Feld Variableninitialisierungen einer Klasse entspricht eine Abfolge von Aufgaben, die in der textlichen Reihenfolge in ausgeführt werden, die sie in der Klassendeklaration erscheinen.

+1

Besser noch, nehmen Sie den Initialisierer für 'Feld' ganz heraus. Alle Felder sind auf Null (oder "null") voreingestellt, wenn das Objekt zum ersten Mal erstellt wird (für statische Felder, wenn der Typ zuerst geladen wird). –

3

Die Reihenfolge der statischen Variablen ändern.

private static int field = 0; 
public static SomeSingleton Default = new SomeSingleton(); 

In Ihrem Code, läuft der Konstruktor erste, was field setzt und field überschreibt dann seinen Wert.

7

Dies liegt an der Reihenfolge der static Variablen. Wenn Sie die beiden Aussagen zu wechseln, wird der Ausgang 1:

private static int field = 0; 

public static SomeSingleton Default = new SomeSingleton(); 

Das ist erwartetes Verhalten wie in MSDN: Static field initialization dokumentiert.

Siehe this .NET Fiddle.

+4

+1 Danke für den Link zu .NET Fiddle, brillantes Werkzeug. –

Verwandte Themen