2014-04-08 7 views
7

Rozważmy następujące klasy:Dziwne zachowanie na statycznych członkach klasy - jak to możliwe?

public class MyClass 
{ 
    public static string[] SomeAmazingConsts = { Const1 }; 
    public static string Const1 = "Constant 1"; 
    public static string Const2 = "Constant 2"; 
} 

Teraz, sprawdź Zastosowanie:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string[] s = MyClass.SomeAmazingConsts; 
     //s[0] == null 
    } 
} 

Problemem jest to, że s [0] == null! Jak do cholery to się stało? Zmień kolejność statycznej zmiennej MyClass w następujący sposób:

public class MyClass 
{ 
    public static string Const1 = "Constant 1"; 
    public static string Const2 = "Constant 2"; 
    public static string[] SomeAmazingConsts = { Const1 }; 
} 

Rzeczy zaczynają działać poprawnie. Czy ktoś może rzucić trochę światła na to?

+0

Jesteś przypisywania pustą referencję do tablicy, nie może magicznie się ponownie przypisany null zmodyfikowana wartość – jedgard

Odpowiedz

11

Od 10.4.5.1 Static field initialization

Statyczne zmienne pole inicjalizatory z klasy odpowiadają na sekwencji zadań, które są wykonywane w kolejności tekstowych w jakiej występują w deklaracji klasy.

Więc inicjalizacji dzieje się od góry do dołu, aw pierwszym przypadku Const1 nie został zainicjowany, stąd

+0

Dlaczego więc kompilator nie powstrzymuje mnie przed "publicznym statycznym ciągiem znaków [] SomeAmazingConsts = {Const1};" linia? Ponieważ Const1 jest zmienną statyczną i nie została jeszcze zainicjalizowana, może (?) Powstrzymać mnie przed jej użyciem zanim zostanie zdefiniowana w pierwszej kolejności. BTW, jak mogę się upewnić, że zmiana kolejności nie wpływa na wykonanie kodu? Jakakolwiek rada? –

+0

Używam ReSharper, a komunikat (tylko ostrzeżenie) stwierdza * Statyczny inicjator pola odnosi się do pola statycznego poniżej lub w innej części *. Więc może warto rozważyć użycie narzędzia do analizy kodu? Ponadto twoja zmienna jest zdefiniowana we właściwym zakresie, po prostu nie jest zainicjalizowana w tym czasie. –

+0

Jednym z oczywistych rozwiązań jest zadeklarowanie tablicy string jako właściwości: public static string [] SomeAmazingConsts {get {return new string [] {Const1}; }} Ale czy można to zrobić? –