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

C# 析構函數、Dispose、Close 三大釋放機制深度解析

     編輯:關於C語言

在 .NET 管理非受控資源(檔案控制代碼、資料庫連線、COM 物件等)時,正確釋放資源至關重要。Finalize (析構函數)、Dispose、Close 三者雖同樣涉及資源釋放,但觸發時機、語意與最佳實踐截然不同。

核心差異速查表

特性析構函數 (Finalize)Dispose()Close()
語意銷毀物件,釋放非受控資源釋放所有資源 (受控+非受控)關閉/釋放資源,視類別設計而定
調用方式GC 自動調用,不可手動呼叫開發人員顯式調用或 using 區塊開發人員顯式調用
調用時機非確定性 (GC 決定)確定性 (離開 using 或手動呼叫)確定性
可重複使用否否 (通常)視類別而定 (如 SqlConnection 可 Reopen)
介面規範無IDisposable無標準介面

深度剖析

Finalize (析構函數) — 最後防線

  • 寫法:~ClassName() { ... },編譯器轉為 override void Finalize()。
  • 只能釋放非受控資源:因 GC 執行時,其他受控物件可能已被回收,存取會不安全。
  • 效能成本高:物件進入 Finalization Queue,需經過兩輪 GC 才真正回收。
  • 建議:除非直接持有非受控資源,否則勿實作 Finalize。

Dispose() — 確定性釋放主力

  • 實作 IDisposable,提供 public void Dispose()。
  • 標準模式 (Dispose Pattern) 採用 protected virtual void Dispose(bool disposing) 區分來源:
public class ResourceHolder : IDisposable
{
    private IntPtr _unmanagedHandle;
    private AnotherDisposable _managedResource;

    // 公開 Dispose
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this); // 告訴 GC 不需再呼叫 Finalize
    }

    // 核心邏輯
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
            // 釋放受控資源
            _managedResource?.Dispose();
        }
        // 釋放非受控資源 (兩種情況都要)
        ReleaseUnmanaged(_unmanagedHandle);
        _unmanagedHandle = IntPtr.Zero;
    }

    // 析構函數:僅釋放非受控
    ~ResourceHolder() => Dispose(false);
}

關鍵點: GC.SuppressFinalize(this) 避免重複釋放並提升 GC 效能。

Close() — 領域特定的關閉語意

  • 無標準規範:由類別設計者決定行為。
  • 常見模式:
    • SqlConnection.Close():歸還連線至連線池,物件可重用 Open()。
    • FileStream.Close():相當於 Dispose(),釋放檔案控制代碼。
  • 設計建議:若類別同時提供 Close 與 Dispose 且皆為 public,通常 Close 呼叫 Dispose,或 Close 只做「邏輯關閉」,Dispose 做「實際釋放」。

實務指導原則

  1. 優先使用 using:確保 Dispose 確定被呼叫。
    using (var conn = new SqlConnection(cs)) { ... } // 編譯器產生 try/finally + Dispose
    
  2. 暫時不用資源:呼叫 Close() (如 SqlConnection),保留物件以便重用。
  3. 永久不用資源:呼叫 Dispose() 或離開 using 區塊。
  4. 類別設計者:持有非受控資源 → 實作完整 Dispose Pattern + Finalize;僅持有受控資源 → 僅實作 IDisposable,無需 Finalize。

總結

Finalize 是安全網,Dispose 是主力,Close 是語意便利。 理解三者分工,才能寫出健壯、高效能的 .NET 程式。

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