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

C# 類成員初始化與構造函數執行順序深度解析(下)

     編輯:關於C語言

承接上篇,本文揭示實際執行順序:派生類字段初始化 → 基類字段初始化 → 基類構造函數 → 派生類構造函數,並通過反例說明為何必須如此設計。

實際執行順序偽代碼

BaseConstructor()
{
    baseFoo = new Foo("Base initializer");
    ObjectConstructor();
    Console.WriteLine("Base constructor");
}

DerivedConstructor()
{
    derivedFoo = new Foo("Derived initializer");
    BaseConstructor();
    Console.WriteLine("Derived constructor");
}

為什麼要這樣設計?

假設按「期望順序」(基類構造函數先於派生類字段初始化)執行,會導致嚴重問題:

class Base
{
    public Base()
    {
        if (this is Derived) ((Derived)this).DoIt(); // 派生類字段尚未初始化 → NullReference
        Blah(); // 若被 MoreDerived 重寫並調用 DoIt,同樣崩潰
    }
    public virtual void Blah() { }
}

class Derived : Base
{
    readonly Foo derivedFoo = new Foo("Derived initializer");
    public void DoIt() { derivedFoo.Bar(); }
}

class MoreDerived : Derived
{
    public override void Blah() { DoIt(); }
}

若基類構造函數先執行,派生類的 readonly 字段 derivedFoo 仍為 null,調用 DoIt 即拋出異常。實際順序保證所有實例字段在任何構造函數體執行前已完成初始化,從而避免此類缺陷。

特別提醒

若 readonly 字段在構造函數中賦值而非初始化器,則上述保護機制失效,需自行確保調用順序安全。

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