早些時候我posted a question關於靜態初始化和不同的調試之間輸出和釋放相同的代碼版本。我所確定的發佈版本產生不同的輸出(實際上它產生沒有輸出)從調試生成因爲DebuggableAttribute
設置允許的JIT優化器,以消除在Release版本的輸出。靜態初始化是不應該運行
我越是想這雖然,它越我的錯誤。我走的更遠之前,讓我告訴從我原來發布的代碼,並在調試版本產生的輸出:
using System;
class Test {
static int value = 0;
static int a = Initialize("Assigning a");
static int b = Initialize("Assigning b");
static String name = "Fred";
static int c = Initialize("Assigning c");
static int Initialize(String mssg) {
++value;
Console.WriteLine("In Initialize() :: {0}, name={1}, returning {2}", mssg, name, value);
return value;
} // Initialize()
static void Main() {
}// Main()
} // class Test
從這個代碼(當與調試版本上運行)的輸出是這樣的:
In Initialize() :: Assigning a, name=, returning 1
In Initialize() :: Assigning b, name=, returning 2
In Initialize() :: Assigning c, name=Fred, returning 3
我瞭解得很清楚,抖動能夠優化掉的輸出,我明白爲什麼會這樣做,所以我不要求任何人來解決之間的調試和發佈版本的差異。
什麼是我的錯誤是爲什麼任何輸出應該出現在第一位。這個類沒有靜態c'tor(這會強制靜態初始化器運行),沒有從類外部引用靜態字段,並且類永遠不會實例化。我要說的是,這個代碼生成的輸出不應該首先生成,至少從我對語言規範的理解來看,甚至不是由Debug生成的。
我一直在鑽研的C#規格的片,我無法找到任何東西,上面寫着靜態初始化應如下所示的代碼運行,無論它的編譯調試或釋放。
任何人都可以解釋爲什麼這代碼應該永遠產生輸出,適用什麼語言規範的一部分?
謝謝。
嘗試在'Main'方法中放置一個斷點,並使用附加的調試器運行代碼。當它打破時,你期望五個領域有什麼價值?在調試和發佈模式下嘗試。還要注意,C#編譯器在技術上將所有初始化器(在聲明中寫入的賦值)移動到靜態類型初始化器。因此,即使C#代碼中沒有靜態構造函數,CLR也會將其視爲靜態方法'.cctor'。但是,CLR可以自由運行或不運行(不參考字段)。在釋放模式下,嘗試一個版本,在'Main'中寫出'name'。 –