2014-03-04 72 views
0

對不起,如果這是一個新手問題,但我找不到像搜索S.O.我已經繼承了一個C#程序來增強,它主要是一個DLL。C#初始化困惑 - 一個獨立的靜態類

我在一種僞代碼中表達了DLL來解釋我的問題: 該DLL有4個類,3個「常規」類和第4類公共靜態變量,這些變量被全局變量用作全局變量該DLL

public class CMain 
    { 
     public CMain() 
     { 
      CFoo Foo = new CFoo(); // CFoo's c'tor is called 
      CBar Bar = new CBar(); // CBar's c'tor is called 
      CGlobals.v1 = 123; 
     } 
    } 



    public class CFoo 
    { 
     ... 
    } 


    public class CBar 
    { 
     ... 
    } 


    public sealed class CGlobals 
    { 
     public static int v1 = 0; 
     public static int v2 = 0; 
    } 

當CMAIN從DLL的調用者實例化,在調試器中CGlobals的靜態變量之前什麼都發生初始化第一的休息。然後CMain的構造函數被調用。

當我查找C#初始化順序時,我發現類的靜態成員在類構造函數被調用之前被初始化,但是CGlobals不是任何成員;它只是坐在那裏,獨自一人,並從其他班級參考。

一切似乎都奏效,但它讓我感到緊張,因爲我不知道它遵循的規則。有人可以解釋一下與此有關的初始化順序規則是什麼,以及這是否有什麼危險?

+0

您確定在調用CMain的構造函數之前初始化了CGLobals靜態字段嗎?爲什麼要在初次使用CGlobals時初次使用它? –

回答

1

靜態成員在實例成員之前被初始化是正確的。此外,實例字段初始值設定項在實例構造函數之前處理,靜態字段初始值設定項在靜態構造函數之前處理字段初始值設定項與層次結構中的構造函數按照相反的順序運行,即大多數派生類的字段將在其基類字段之前初始化。

第一次訪問類型的成員時發生靜態初始化。因此,雖然CGlobals可能不會在CMain的同一時間初始化,但其成員將在您第一次嘗試訪問時初始化。

這種行爲有個例外:在.NET 4.0及更高版本中運行「release」程序集時,運行時可能會推遲靜態字段初始值設定項。第一次嘗試訪問它們時,初始化的值仍然可用,但它們可能不會全部立即初始化,或者按照它們聲明的順序進行初始化。儘管如此,依賴關係仍應該得到尊重。如果你正在處理標量值,並且初始值設定項沒有產生副作用,那麼這些都不會對你產生影響。

1

是的,靜態變量在任何構造函數被調用之前被初始化。這些靜態變量的值只能依賴於其他靜態變量。

1

靜態變量將被初始化,然後您可以調用它......但是有什麼理由不能使用靜態類嗎?

public static class CGlobals 
{ 
    public static int v1=0; 
    public static int v2 = 0; 
} 

這是您試圖完成的更好的表示。

+0

不知道。我沒有寫。我只是想確保C#保證執行單元中的所有靜態變量都是首先初始化的,因爲當我查找規範時,所有可能發現的地方都是靜態成員首先被初始化。 – user316117

1

靜態構造函數在任何對類的訪問之前被調用。任何嘗試訪問非初始化類(具有靜態構造函數)都會導致調用靜態構造函數。

訪問可以是:

  • 創建類的實例(對象)
  • 靜態成員函數調用
  • 訪問(讀取或寫入)的任何靜態屬性
  • 訪問任何靜態字段