先看一道常見題目,以下代碼的執(zhí)行結果是什么?
class A { public static int X = B.Y + 1; static void Main(string[] args) { Console.WriteLine(X); } } class B { public static int Z = 10; public static int Y; static B() { Console.WriteLine(Z); Y = A.X + 1; } }
一、定義
由名稱可知,靜態(tài)構造函數(也稱為類型構造函數)包含“靜態(tài)”和“構造函數”兩個特點。第一個特點決定了它與靜態(tài)函數類似,只能使用靜態(tài)成員;第二個特點決定了它與構造函數類似,具有初始化作用,并且沒有返回值。
與構造函數(針對實例對象)不同的是,靜態(tài)構造函數(針對類)只執(zhí)行一次,并且是在第一個實例對象創(chuàng)建前被調用,所以它可以用于那些只需要執(zhí)行一次的操作;而且它不允許有public等修飾符,由程序自動調用,不能被外界調用。
總結:靜態(tài)構造函數用于初始化任何靜態(tài)數據,或者用于執(zhí)行僅需執(zhí)行一次的操作;在創(chuàng)建第一個實例對象或者引用任何靜態(tài)變量之前,將自動調用靜態(tài)構造函數。
特點:
1、靜態(tài)構造函數既沒有訪問修飾符,也沒有參數。
2、在創(chuàng)建第一個實例或引用任何靜態(tài)成員之前,將自動調用靜態(tài)構造函數來初始化類。
3、無法直接調用靜態(tài)構造函數。
4、在程序中,用戶無法控制何時執(zhí)行靜態(tài)構造函數。
5、線程安全。
關于線程安全需要特別說明一下,由于程序可能在多線程環(huán)境下運行,也就是可能出現同時多個線程準備執(zhí)行靜態(tài)構造函數的情況。CLR確保這個過程是安全的,實際上調用靜態(tài)構造函數的線程需要先獲得一個互斥線程同步鎖,如果有多個線程試圖執(zhí)行類型的靜態(tài)構造函數,只有一個線程能獲得該鎖;獲得鎖的線程完成初始類型初始化操作,其它線程只能等待;當初始化完成,等待的線程被喚醒,然后發(fā)現靜態(tài)構造函數已經被執(zhí)行過,就不會再執(zhí)行。
二、語法
public class StaticTester { static StaticTester() { } }
三、作用
用于初始化靜態(tài)成員。有時候我們會從配置文件讀取一些值作為靜態(tài)變量,類似這樣:
public class StaticTester { PRivate static readonly string key = ConfigurationManager.AppSettings["key"]; private static readonly string value = ConfigurationManager.AppSettings["value"]; static StaticTester() { } }
如果要讀取的配置信息比較多,而且要加入一些邏輯判斷,那么可以這樣:
public class StaticTester { private static readonly string key; private static readonly string value; static StaticTester() { key = ConfigurationManager.AppSettings["key"]; if (string.IsNullOrEmpty(key)) { throw new Exception("key變量未被正確配置!"); } value = ConfigurationManager.AppSettings["value"]; if (string.IsNullOrEmpty(value)) { throw new Exception("value變量未被正確配置!"); } } }
四、執(zhí)行順序
1. 運行時,優(yōu)先對靜態(tài)變量進行初始化。
2. 如果有靜態(tài)構造函數,那么在創(chuàng)建第一個實例對象或者引用任何靜態(tài)變量之前,調用靜態(tài)構造函數。
3. 其它操作。
新聞熱點
疑難解答