2015-09-11 24 views
7

根據Jon Skeet的artice C# and beforefieldinit以及在When is a static constructor called in C#?中的討論必須先調用靜態構造函數,然後才能首先調用類的方法。爲什麼靜態構造函數在第一次調用類方法之前未被調用

出於某種原因,下面的代碼不會出現此行爲:

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"); 
     } 
    } 
}  

我調試使用Visual Studio調試器上面的代碼。當在Main方法中執行語句StaticClass.Equals(1,2);時,靜態構造函數不會被調用,但當執行StaticClass.foo();時,它會調用靜態構造函數,然後調用foo方法。

我有點困惑,爲什麼它在執行StaticClass.Equals(1,2);時第一次沒有被調用。

+0

我相信你需要重寫Object.Equals。就目前而言,這是調用基礎版本。每個類都從對象btw繼承,所以不需要手動完成。 –

+0

你寫的Equals()方法在哪裏? –

+0

@MicrosoftDN它繼承自Object.Equals' –

回答

12

您對StaticClass.Equals呼叫實際上只是Object.Equals(Object, Object)的調用,如StaticClass沒有提供Equals適用的過載。如果你看看IL,你會發現編譯器已經將呼叫解決到Object.Equals(1, 2)。如果您沒有調用實際涉及靜態類的方法,則不需要進行初始化。

+0

請注意,「它不需要被初始化」 - 如果框架決定早些時候調用靜態構造函數,它仍然是有效的行爲。 –

+2

@AlexeiLevenkov:不,它不會。如果一個類型有一個靜態構造函數,那麼它保證只有在第一次引用該類的成員之前立即執行。您可能正在考慮什麼時候沒有靜態構造函數的類型被初始化,這比較寬鬆。具體來說,從C#規範:「靜態構造函數的執行是由在應用程序域內發生以下第一個事件觸發的:\t創建類類型的實例\t類類型的任何靜態成員被引用。「 –

+0

@AlexeiLevenkov:另見:http://csharpindepth.com/Articles/General/Beforefieldinit.aspx –

相關問題