2015-09-11 9 views
7

Zgodnie z artykulem Jona Skeeta C# and beforefieldinit i dyskusją w When is a static constructor called in C#? konstruktor statyczny musi zostać wywołany przed pierwszym wywołaniem metody klasy.Dlaczego konstruktor statyczny nie jest wywoływany przed pierwszym wywołaniem metody klasy

Z jakiegoś powodu następującego kodu nie wykazuje tego zachowania:

namespace AbstractAndStatic 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      StaticClass.Equals(1,2); 
      StaticClass.foo(); 
     } 
    } 
    static class StaticClass : Object 
    { 
     public static void foo() 
     { 
      Console.WriteLine("Static"); 
     } 
     static StaticClass() 
     { 
      Console.WriteLine("static constructor"); 
     } 
    } 
    class TestClass 
    { 
     public void deb() 
     { 
      Console.WriteLine("Test Class Debug"); 
     } 
    } 
}  

jestem debugowania powyższy kod przy użyciu Visual Studio Debugger. Gdy instrukcja StaticClass.Equals(1,2); zostanie wykonana w metodzie głównej, statyczny konstruktor nie zostanie wywołany, ale po wykonaniu StaticClass.foo(); wywołuje konstruktor statyczny, a następnie wywołuje metodę foo.

Jestem trochę zdezorientowany, ponieważ nie został wywołany po raz pierwszy podczas wykonywania StaticClass.Equals(1,2);.

+0

Uważam, że należy zastąpić Object.Equals. W obecnej wersji nazywa się wersję podstawową. Każda klasa dziedziczy po obiekcie btw, więc nie trzeba tego robić ręcznie. –

+0

Gdzie jest zapisana twoja metoda Equals()? –

+0

@MicrosoftDN odziedziczona po 'Object.Equals' –

Odpowiedz

12

wezwanie do StaticClass.Equals jest faktycznie tylko wezwanie do Object.Equals(Object, Object), jak StaticClass nie zapewnia zastosowanie przeciążenia dla Equals. Jeśli spojrzysz w IL, zobaczysz, że kompilator rozwiązał połączenie tylko do Object.Equals(1, 2). Jeśli nie wywołujesz metody, która w rzeczywistości dotyczy klasy statycznej, nie trzeba jej inicjować.

+0

Zauważ, że "nie * trzeba * być zainicjalizowane" - nadal byłoby prawidłowe zachowanie, jeśli framework zdecyduje się wcześniej wywołać konstruktor statyczny. –

+2

@AlexeiLevenkov: Nie, nie byłoby. Jeśli typ ma konstruktor statyczny, gwarantuje się, że zostanie on wykonany * bezpośrednio * przed pierwszym odniesieniem do elementu tej klasy. Być może myślisz o tym, kiedy typ bez statycznego konstruktora zostanie zainicjowany, co jest znacznie łagodniejsze. Konkretnie, ze specyfikacji C#: "Wykonanie statycznego konstruktora jest wyzwalane przez pierwsze z następujących zdarzeń, które mają wystąpić w domenie aplikacji: \t Utworzono instancję typu klasy: \t Dowolny ze statycznych elementów typu klasy są przywoływane. " –

+0

@AlexeiLevenkov: Zobacz także: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx –

Powiązane problemy