首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

《Effective C#》精要:善用成員初始化語句,避開常見陷阱

     編輯:關於C#

在探討成員初始化語句之前,我們先釐清物件的建構流程。當類型的第一個實例被建立時,執行順序大致如下:

  1. 配置靜態成員的記憶體空間(初始值為 0);
  2. 執行靜態成員的初始化語句;
  3. 執行基類的靜態建構函式;
  4. 執行該類型的靜態建構函式;
  5. 配置執行個體成員的記憶體空間(初始值為 0);
  6. 執行成員的初始化語句;
  7. 執行基類的建構函式;
  8. 執行該類型的建構函式。

對於同類型後續建立的物件,前四個步驟會被略過,直接從第 5 步開始。

為何推薦使用成員初始化語句?

成員初始化語句在建構函式之前執行,因此能更早完成初始化,方便後續使用;此外,它能避免在多個建構函式中重複撰寫初始化碼,特別是新增欄位時,將初始化邏輯放在欄位宣告處,可減少因建構函式不一致導致某些成員未被初始化的風險。程式碼也因此更簡潔易讀。

public class MyList
{
    // 成員初始化語句
    private ArrayList _list = new ArrayList();
}

三種不適合使用成員初始化的情境

雖然成員初始化語句很好用,但並非萬能。以下三種情況應避免使用:

1. 將成員指派為 0 或 null

這並非錯誤,但屬於多餘操作。根據建構流程,成員在配置記憶體時已自動以 0 初始化,顯式指派只會增加指令、降低效能。

2. 需根據建構函式參數決定初始化方式

若在成員初始化語句中建立物件,又在建構函式中依參數重新指派,會產生短暫的暫存物件,增加 GC 壓力。例如:

public class MyList
{
    private ArrayList _list = new ArrayList(); // 成員初始化
    public MyList() { }
    public MyList(int nSize)
    {
        _list = new ArrayList(nSize); // 重新指派,前一個 ArrayList 成垃圾
    }
}

較佳做法是移除成員初始化,改在各建構函式中統一處理:

public class MyList
{
    private ArrayList _list;
    public MyList() { _list = new ArrayList(); }
    public MyList(int nCount) { _list = new ArrayList(nCount); }
}

3. 初始化過程可能拋出例外,且需在類別內部處理

成員初始化語句無法包裹 try-catch,例外會直接向外傳播,迫使呼叫端處理,導致呼叫端代碼繁瑣。此時應改用建構函式,在內部捕獲並處理例外:

public class MyTest
{
    private TempObject _value;
    public MyTest()
    {
        try { _value = new TempObject(); }
        catch (Exception err) { /* 內部處理 */ }
    }
}

小結

成員初始化語句能提升程式碼清晰度並減少重複,但需避開上述三種情境。筆者個人傾向使用建構函式初始化,並透過建構函式鏈結(this())解決多建構函式的重複問題,這純屬個人偏好,專案可依團隊規範決定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved