文章目錄
- 1.初始化對象為0或null時
- 2.對同一個變數執行不同的初始化方式
- 3.需要進行異常處理
一般情況下,一個類都會有多個建構函式。隨著時間的推移,成員變數、建構函式不斷增加。為了處理這種情況最方便的辦法就是:在聲明變數的時候進行初始化,而不是在每個建構函式中進行。無論是類成員(靜態變數)合適執行個體變數,我們都應該充分利用初始化器的文法。
C#編程在,一般在聲明一個變數的同時我們會對其進行初始化:
1 class Employee2 {3 private List<Employee> empList = new List<Employee>();4 }
不論我們為Employee類添加了多少個建構函式,empList變數都能夠被正確的初始化,這是因為:
編譯器會在所有的建構函式(包括預設建構函式)的最開始位置產生代碼來為所以的執行個體成員變數定義初始化器(進行初始化);所以我們不需要再建構函式中為每一個定義的成員變數添加初始化代碼——直接在聲明的時候初始化即可。
初始化器可以看做是建構函式中初始化語句的另一種表示。初始化器產生的程式碼會插入到建構函式代碼前面執行。初始化器將在為類型執行調用基類建構函式之前執行,其順序與類成員變數聲明的順序一樣。
C#的初始化器文法是一種最簡單的、能夠避免類型中存在未初始設定變數的解決辦法。但是在下面的三種情況下應該避免使用初始化器:
1.初始化對象為0或null時
因為系統預設的初始化會將會在所有代碼執行前把一切都設定成0或者null(實值型別和參考型別)。而且這一步的操作是位於很底層的實現,我們也可以直接將對象賦值設定為0或null,但是顯然這是多餘的。
2.對同一個變數執行不同的初始化方式
使用初始化語句的一個前提是:所有得建構函式都將為該變數設定同樣的值。我們看下面的範例程式碼:
1 class Employee 2 { 3 //聲明變數的同時進行初始化 4 private List<Employee> empList = new List<Employee>(); 5 6 public Employee() 7 { 8 } 9 10 public Employee(int size)11 {12 empList = new List<Employee>(size);13 }14 }
在上面的代碼中,當我們調用第二個建構函式建立初始化指定大小的泛型集合時 ,實際上時建立了兩個List<Employee>。第一個建立後馬上變成了垃圾——這是由於初始化器將在所有建構函式之前執行。編譯器產生的程式碼類似於下面的這段代碼:
1 class Employee 2 { 3 //聲明變數 4 private List<Employee> empList; 5 6 public Employee() 7 { 8 empList = new List<Employee>(); 9 }10 11 public Employee(int size)12 {13 empList = new List<Employee>();14 empList = new List<Employee>(size);15 }16 }
我們可以看到這樣做會影響程式的效率,建立了不必要的對象,所以如果需要在不同的建構函式中執行不同的初始化方式時正確的做法應該是不適用初始化器,而是先聲明變數,然後在建構函式中進行成員變數的初始化,如下:
1 class Employee 2 { 3 //聲明變數 4 private List<Employee> empList; 5 6 public Employee() 7 { 8 empList = new List<Employee>(); 9 }10 11 public Employee(int size)12 {13 empList = new List<Employee>(size);14 }15 }
3.需要進行異常處理
初始化器無法被try語句包裹。所以對象初始化器執行的過程中發生異常都會被傳遞到對象之外。如果在初始化對象的時候可能會拋出異常時我們應該將這部分代碼放到建構函式中,對其進行異常處理。這樣才能夠實現必要的恢複性代碼,以建立類型執行個體並以更友好的方式處理異常。
小節:
成員初始化器是保證類型中成員變數都被初始化的最簡單方法——在聲明變數時就對其進行初始化,無論調用的是那個建構函式,初始化器都將會在所有建構函式之前執行。這種文法也避免了在添加新的建構函式時遺漏掉重要的初始化代碼。所以,如果對於所有的建構函式某個成員變數的初始化值是一樣的,那麼就應該盡量使用初始化器文法。