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

全面認識 C#(二十三):建構子與解構子/Finalize/Dispose 模式

     編輯:C# 入門

前言

C# 物件生命週期管理包含建構子初始化、解構子清理、Dispose 模式釋放非受控資源。理解三者差異與最佳實務,是寫出健壯程式的關鍵。

建構子

多載與鏈結


public class Person {
    public string Name { get; }
    public int Age { get; }
    public Address Address { get; }

    public Person() : this("Unknown", 0) { } // 呼叫另一建構子
    public Person(string name) : this(name, 0) { }
    public Person(string name, int age) : this(name, age, null) { }
    public Person(string name, int age, Address address) {
        Name = name; Age = age; Address = address;
    }
}

靜態建構子


public class Config {
    public static readonly string ConnectionString;
    public static readonly int MaxConnections;

    static Config() { // 僅執行一次,執行緒安全
        ConnectionString = LoadFromConfig();
        MaxConnections = Environment.ProcessorCount * 2;
    }
}

解構子 / Finalize

語法與特性


public class ResourceHolder {
    private IntPtr _handle;

    ~ResourceHolder() { // 解構子語法 (C# 編譯為 Finalize)
        ReleaseHandle(_handle);
        Console.WriteLine("Finalized");
    }

    private void ReleaseHandle(IntPtr handle) { /* 釋放非受控資源 */ }
}
  • 不可多載、不可繼承、不可顯式呼叫
  • 僅適用參考型別 (類別),結構無解構子
  • GC 執行時非決定性呼叫,順序不可預測
  • 例外未處理會終止 Finalize 執行緒

與 C++ 解構子差異

特性C++ 解構子C# 解構子 (Finalize)
呼叫時機離開作用域/刪除時確定性呼叫GC 非決定性呼叫
記憶體釋放開發者負責GC 自動
例外安全RAII 保證無保證

Dispose 模式 (IDisposable) - 微軟標準模式

完整實作範本


public class ResourceWrapper : IDisposable {
    private IntPtr _handle;
    private bool _disposed;

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

    protected virtual void Dispose(bool disposing) {
        if (_disposed) return;
        if (disposing) {
            // 釋放受控資源 (其他 IDisposable 物件)
        }
        // 釋放非受控資源
        ReleaseHandle(_handle);
        _handle = IntPtr.Zero;
        _disposed = true;
    }

    ~ResourceWrapper() => Dispose(false); // Finalize 只釋放非受控

    private void ReleaseHandle(IntPtr handle) { /* 釋放非受控 */ }
}

using 陳述式 (C# 8.0+ using 宣告)


// 傳統
using (var resource = new ResourceWrapper()) {
    resource.DoWork();
} // 自動呼叫 Dispose()

// C# 8.0+ 範圍式
using var resource = new ResourceWrapper();
resource.DoWork();
// 區塊結束自動 Dispose

非受控資源類型

  • 檔案控制代碼、Socket、資料庫連線
  • GDI 物件 (Bitmap, Brush, Pen)、COM 物件
  • 非受控記憶體 (Marshal.AllocHGlobal)
  • 事件訂閱 (需取消訂閱避免記憶體洩漏)

進階:SafeHandle 封裝非受控資源


public class MySafeHandle : SafeHandleZeroOrMinusOneIsInvalid {
    public MySafeHandle() : base(true) { }
    protected override bool ReleaseHandle() {
        return NativeMethods.CloseHandle(handle);
    }
}

// 使用
using (var handle = new MySafeHandle()) {
    // handle 自動釋放,不可偽造、執行緒安全
}

分散式/非同步情境

  • IAsyncDisposable (C# 8.0+):await using 非同步釋放
  • 分散式物件:.NET Remoting/WCF 參考計數問題,建議使用狀態服務

總結

建構子負責初始化,靜態建構子保證型別初始化一次。解構子 (Finalize) 是 GC 最後防線,不可依賴釋放關鍵資源。Dispose 模式是釋放非受控資源的標準方式,配合 using 確保確定性清理。SafeHandle 進一步封裝非受控控制代碼,提供更安全的抽象層。

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