[英]Which static class initializes first?
如果我們的項目中還有一個靜態類,那么哪個靜態類首先初始化?
例如:下面的代碼給出了null異常。
class Program
{
static void Main(string[] args)
{
First.Write();
Second.Write();
}
}
static class First
{
public static int[] firstArray = new int[20];
public static int[] secondArray = Second.secondArray;
public static void Write()
{
Console.WriteLine(firstArray.ToString());
Console.WriteLine(secondArray.ToString());
}
}
static class Second
{
public static int[] firstArray = First.firstArray;
public static int[] secondArray = new int[30];
public static void Write()
{
Console.WriteLine(firstArray.ToString());
Console.WriteLine(secondArray.ToString());
}
}
如果你留意,你會看到,如果First
類將初始化自身, secondArray
場Second
將是空的。 但是如果Second
類首先初始化,那么Second
class firstArray
將為null。 我試圖告訴哪個初始化首先產生不同的結果。
我認為這是關於我的項目的抽象問題。 我在試圖理解為什么會得到意想不到的結果時遇到它。
First
將開始初始化,分配firstArray
,然后注意它需要初始化Second
才能獲得secondArray
的初始值。
Second
將開始初始化,然后注意它需要First進行初始化。 但是,CLR會注意到First 已經在當前線程中初始化,因此它不會阻塞。 Second
初始化將完成,然后First的初始化將完成。
幸運的是, Second
需要的領域已被分配,因此“正確的事情”發生了。
如果First
實際上 First
開始初始化,那就非常好了。 但是,因為這兩個類都沒有靜態構造函數,所以Second
可能會先開始初始化......然后它會開始初始化First
,這會發現Second
已經初始化並獲取Second.secondArray
的當前值( null)對於First.secondArray
。 這將是一件壞事。 請注意,沒有靜態構造函數的類型的初始化時序在.NET 4中已經發生了變化 - 不是以破壞規范的方式,而是以現有的代碼破解方式。
如果First
和Second
都有靜態構造函數,那么First
將First
被初始化,因為它是Main
接觸的第一個類。
答案的道德:不要這樣做。 相互引用的類型初始化器非常容易出錯。 再舉一個例子,請參閱Eric Lippert和Neal Gafter的NDC 2010演講,“C#Puzzlers”,可以在NDC視頻頁面上觀看。
我不相信有任何關於首先初始化靜態類型的保證。 要確保以這種方式正確初始化字段,您需要添加一個靜態構造函數,例如:
static class Second
{
public static int[] firstArray = First.firstArray;
public static int[] secondArray = new int[30];
static Second() { }
public static void Write()
{
Console.WriteLine(firstArray.ToString());
Console.WriteLine(secondArray.ToString());
}
}
現在,當你再次運行同樣的東西時,它的工作原理......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.