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

C# 物件初始化完整解析(二):建構順序陷阱與兩階段建構模式

     編輯:關於C語言

實際輸出驗證初始化順序


Derived.Static.Field1
Derived.Static.Field2
Derived.Static.Constructor
Derived.Instance.Field1
Derived.Instance.Field2
Base.Static.Field1
Base.Static.Field2
Base.Static.Constructor
Base.Instance.Field1
Base.Instance.Field2
Base.Instance.Constructor
Base.Instance.Field3
Derived.Instance.Virtual
Derived.Instance.Constructor
Derived.Instance.Field3

關鍵觀察:建構函數執行順序反轉

  • 靜態/欄位初始化:派生類 → 基類 (Derived → Base)
  • 實例建構函數:基類 → 派生類 (Base → Derived)

虛方法呼叫陷阱

基類建構函數呼叫 Virtual() 時,派生類建構函數尚未執行,派生類欄位 Field3 仍未初始化。輸出顯示 Derived.Instance.Virtual 在 Derived.Instance.Field3 之前!

錯誤範例


class Base {
    public Base() { Virtual(); } // 危險!
    virtual public void Virtual() { Console.WriteLine("Base"); }
}
class Derived : Base {
    private Tracker field3 = new Tracker("Derived.Field3");
    override public void Virtual() { 
        Console.WriteLine(field3); // NullReferenceException 風險
    }
}

正確模式:兩階段建構


// 階段 1:建構物件
Derived d = new Derived();

// 階段 2:初始化邏輯 (安全呼叫虛方法)
d.Virtual(); // 此時 Derived 完全初始化完成

C# 物件初始化黃金法則總結

  1. 欄位先於建構函數:欄位初始化 → 建構函數執行
  2. 靜態先於實例:類別首次存取時靜態初始化 → 實例化
  3. 派生先於基類 (靜態/欄位):C → B → A
  4. 基類先於派生 (實例建構函數):A → B → C
  5. 勿依賴宣告順序:工具/重構可能調整欄位順序
  6. 虛方法採兩階段建構:建構完成後再呼叫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved