2014-07-24 13 views
13

Znalazłem zachowanie C#, które chciałbym zrozumieć. Rozważmy klasę takiego:C# pole statyczne, konstruktor wystąpienia

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

    private static int field = 0; 

    private SomeSingleton() 
    { 
     field = 1; 
    } 

    public int GetField() 
    { 
     return field; 
    } 
} 

Teraz nazwijmy metodę GetField():

var field = SomeSingleton.Default.GetField(); 

jestem coraz 0 jakby konstruktor instancja została pominięta. Czemu?

Odpowiedz

26

Po prostu zamień kolejność deklaracji field przed Default.

więc linie:

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

powinno być:

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

Powodem jest to, ze względu na celu inicjalizacji pola. Najpierw Default zostaje zainicjowany w kodzie, który przypisuje wartość field o wartości 1. Później to pole jest przypisywane 0 podczas inicjalizacji. Stąd widać najnowszą wartość 0, a nie 1.

Patrz: 10.4.5.1 Static field initialization

Pole statyczne zmienne inicjalizatory z klasą odpowiadać sekwencji zadań, które są wykonywane w kolejności tekstowej w jakiej występują w deklaracji klasy.

+1

Co więcej, całkowicie wyeliminuj inicjator dla 'pola'. Wszystkie pola są ustawione na zero (lub 'null'), gdy obiekt jest najpierw tworzony (dla pól statycznych, gdy typ jest ładowany po raz pierwszy). –

3

Zmienić kolejność zmiennych statycznych.

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

W kodzie, konstruktor biegnie pierwszy, który ustawia field, a następnie field zastępuje jego wartość.

7

Dzieje się tak, ponieważ zamawiamy zmienne static. Jeśli przełączyć dwa oświadczenia, wyjście staje 1:

private static int field = 0; 

public static SomeSingleton Default = new SomeSingleton(); 

Jest to oczekiwane zachowanie jako udokumentowane w MSDN: Static field initialization.

Zobacz this .NET Fiddle.

+4

+1 Dzięki za link do .NET Fiddle, genialne narzędzie. –