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

C# 建構函式與解構函式 (Finalizer) 完整解析

     編輯:關於C#

建構函式分類

1. 靜態建構函式

  • 關鍵字:static ClassName()
  • 用途:初始化靜態欄位、執行一次性類別層級設定。
  • 特性:無參數、無存取修飾詞、CLR 自動在首次使用類別前呼叫一次、不可繼承。

2. 實例建構函式

  • 關鍵字:public ClassName(...)
  • 用途:初始化實例欄位。
  • 特性:可多載、可有參數、可呼叫 base(...) 或 this(...)。
  • 預設:若無任何建構函式,編譯器提供無參數預設建構函式;一旦自定義,預設即消失。

3. 私有建構函式

  • 用途:單例模式、工廠模式、靜態類別 (僅含靜態成員) 防止實例化。

繼承鏈建構順序

class Base
{
    public Base() { Console.WriteLine("Base()"); }
    public Base(int x) { Console.WriteLine($"Base({x})"); }
}

class Derived : Base
{
    public Derived() { Console.WriteLine("Derived()"); }
    public Derived(int x, int y) : base(x) { Console.WriteLine($"Derived({x},{y})"); }
}

// new Derived()       → Base() → Derived()
// new Derived(1,2)    → Base(1) → Derived(1,2)

規則:基類建構函式先於衍生類;若衍生類未顯式呼叫 base(...),隱式呼叫基類無參建構函式 (基類必須有無參建構函式)。

解構函式 / Finalizer

  • 語法:~ClassName() { ... } (C# 語法糖,編譯為 Finalize() 覆寫)。
  • 用途:釋放非受控資源 (檔案控制碼、資料庫連線、原生記憶體、COM 物件)。
  • 特性:無參數、無修飾詞、不可呼叫、由 GC 執行緒在物件回收前非確定性呼叫。

Dispose 模式 (標準資源釋放模式)

public class ResourceHolder : IDisposable
{
    private IntPtr _nativeHandle; // 非受控資源
    private bool _disposed;

    // 建構函式取得資源
    public ResourceHolder() => _nativeHandle = NativeOpen();

    // 公開 Dispose
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this); // 已手動清理,通知 GC 不需呼叫 Finalizer
    }

    // 核心清理邏輯
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing)
        {
            // 釋放受控資源 (其他 IDisposable 物件)
        }
        // 釋放非受控資源
        if (_nativeHandle != IntPtr.Zero)
        {
            NativeClose(_nativeHandle);
            _nativeHandle = IntPtr.Zero;
        }
        _disposed = true;
    }

    // Finalizer (保障機制)
    ~ResourceHolder() => Dispose(false);
}

關鍵原則

  1. 受控資源:由 GC 管理,不需 Finalizer,在 Dispose(true) 中釋放。
  2. 非受控資源:GC 不知道如何釋放,**必須**在 Dispose(false) 和 Finalizer 中釋放。
  3. 無非受控資源:不要寫 Finalizer,會增加 GC 壓力 (物件進入 Finalization Queue,需兩輪 GC 才能回收)。
  4. using 區塊:自動呼叫 Dispose(),確保釋放時機確定性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved