[C#]Effective C# 條款十二:變數初始器優於賦值語句


何謂變數初始器?變數初始器是.NET底層用於初始化變數的一種機制,運行於基底類別建構子建構之前,其初始變數的順序與類別中變數宣告的順序相同,是確保類別中成員變數能正確初始化的最簡單的方法,可用以避免程式中出現未初始化的變數。





您也許沒有聽過變數初始器這樣的名詞,但相信應該都曾在不知不覺中使用過它,像是下面這樣的例子,假設我們需要在類別中宣告一個物件,並希望能在宣告時就順便建立物件實體,我們可能會在類別下方直接宣告並建立實體,這樣的寫法就是用到了變數初始器來幫助我們初始化變數。




Class TestClass{
Object _obj = new Object();

}





變數初始器應用於不同建構子具相同初始化動作的變數上,因其運作於建構子之前,故將變數初始化的動作從建構子提出到變數初始器,可避免因後續增加建構子而漏初始物件的冏境。但在下列情況我們應當避免使用:





1.將變數初始為0或null



因為底層自行會透過CPU指令將記憶體清空,清空後的狀態就是0或null,故若自行撰寫賦值語句將數值設為0或是將物件設為null,程式會忠實的幫你運行你的要求,這就是不必要的額外負擔。



p.s.其實這多餘的動作應該編譯器是可以濾掉的,目前尚無法證實底層是否是如書上所述的運作,不過不必要的多餘程式能減少撰寫也是該減少。





2.不同建構子具不同初始化動作的變數



對於不同建構子可能會有不同初始化動作的變數,我們不該將其從建構子中提出放置變數初始器中去初始變數。不然可能需重新建立新的物件實體,而變數初始器中初始的物件很快就會變成記憶體中的垃圾,是不必要的浪費。




Class TestClass{
ArrayList _obj = new ArrayList();

TestClass()
{
}
TestClass(int size)
{
_obj = new ArrayList(size);
}
}





3.初始時會例外的變數



因為變數初始器無法使用異常處理,故若變數在初始化時可能會造成例外的發生,可將變數初始化動作從變數初始器移到建構子之中,在建構子中使用例外處理來處理例外。





另外一提,變數初始器雖然是確保類別中成員變數能正確初始化的最簡單的方法,但個人覺得這樣的方法可能不是最好的方法,因其存在著一些問題,會讓變數初始的動作都集中在某一個時間點,造成建立物件時需要耗費許多的時間來做初始成員的動作,這些初始的成員變數也並非是這次建構一定會被用到的,若你也有這種的考量的話可考慮採用Lazy initialization的方式來處理。