2013-02-13 68 views
0

我知道,靜態構造函數總是優先,並在任何實例構造函數之前被調用。然而,考慮一下我有一個實例類和一個靜態類的場景。我想知道爲什麼結果是首先從基類和靜態類?我也驗證了交換呼叫,我相應地得到了​​結果。但是我錯在我的想法中:靜態類總是應該首先被調用,而不管其他實例類是什麼?爲什麼這引發我是因爲,我看到某個地方,當包含該類的命名空間被觸發時,靜態類會自動加載。然後,我期望靜態構造函數首先觸發。爲什麼不發生?有人能以一種可以理解和簡單的方式解釋嗎?靜態類不會先被調用,而會被實例類調用。爲什麼?

public class Base 
    { 
     public Base() { Console.WriteLine(" I am from normal Base constructor"); } 
     static Base() { Console.WriteLine("Hey I am from Static Base"); } 
    } 
    public static class Base1 
    { 
     static Base1() { Console.WriteLine("I am from Static Constructor"); } 
     public static void StaticMethod() { Console.WriteLine("I am from Static Method"); }    
    } 

    static void Main(string[] args) 
    { 
     Base b = new Base(); 
     Base1.StaticMethod(); 
     Console.Read(); 
    } 
+0

你在哪裏閱讀當包含該類的命名空間被觸發時,靜態類會自動加載? – Paparazzi 2013-02-13 13:16:23

+0

「我在某處看到,當包含該類的命名空間被觸發時,靜態類會自動加載。」你如何「觸發」命名空間?這根本不符合邏輯。請發佈一個鏈接到神祕的「某處」,但不清楚它們的含義。 – dasblinkenlight 2013-02-13 13:17:46

+0

嗨Blam和dasb,對不起,如果我誤解了,但你可以在MSDN中看到類似的聲明http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx – Learner 2013-02-13 13:19:23

回答

0

靜態構造函數只有在實際需要時纔會調用。如果他們需要,他們保證在他們的班級的正常構造函數之前被調用。

但是不能保證所有的靜態構造函數都會在任何不同類的普通構造函數之前被調用。

它不可能做到這一點,並避免調用未使用的靜態構造函數。你可以做一些事情,比如只在程序結束之前用一個靜態構造函數訪問一個類,然後只在某些條件滿足時才做。顯然,代碼無法及時提前對等以確定是否需要靜態構造函數調用;因此,在代碼訪問它之前,沒有辦法調用靜態構造函數。

查看Eric Lippert's Blog about Static Constructors瞭解更多詳情!

+0

非常感謝你,馬修,幫助我。 – Learner 2013-02-13 13:24:00

1

只有一個保證:

一類的靜態構造函數的任何實例構造函數或類的任何靜態成員之前調用。

這個保證沒有說明靜態構造函數被調用的時間。大多數情況下,當靜態類實際被使用時它會被調用 - 而不是更早。

在創建另一個類的實例之前,沒有理由執行靜態構造函數。

你說:

我看到某處時,將觸發包含類的命名空間時,靜態類自動加載。

這是不正確的,我想你可能誤解了那裏的東西。

的MSDN指出以下:

靜態類由當被加載包含類的程序或命名空間的.NET Framework公共語言運行庫(CLR)自動加載。

我明白這可能會被誤解。這裏的「加載類」並不意味着它的構造函數被執行。這意味着CLR只需加載類型並對其進行驗證。

+0

非常感謝你,是的,我可能誤解了MSDN中給出的陳述:(我對MSDN解釋大多數時間都不太舒服。http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs .80).aspx – Learner 2013-02-13 13:23:16

+0

@Divine:請參閱我的回答更新 – 2013-02-13 13:25:55

+0

哦,現在你的解釋讓我明白MSDN的聲明,我想,加載方法,解僱了構造函數。 ) – Learner 2013-02-13 13:28:49

1

根據MSDN:

靜態構造用於初始化任何靜態數據,或執行 需要僅一次執行的特定動作。在創建第一個實例或引用任何 靜態成員之前自動調用 。

所以在你的情況下 - 首先你要調用基類的構造函數,然後你訪問Base1的靜態方法。

+0

謝謝你的回答:) – Learner 2013-02-13 13:24:19

相關問題