.NET 垃圾收集器 (GC) 僅管理受控記憶體。非受控資源 (檔案控制代碼、資料庫連線、GDI+ 物件、COM 物件、記憶體指標等) 必須由開發者明確釋放。IDisposable 模式提供決定性釋放機制。
| 成員 | 呼叫時機 | 呼叫者 | 用途 |
|---|---|---|---|
~Finalize() (析構函式) | GC 回收物件時 (非決定性) | Finalizer Thread | 防禦性釋放非受控資源,防止使用者忘記呼叫 Dispose |
Dispose() | 使用者明確呼叫 (決定性) | 程式碼撰寫者 | 立即釋放受控 + 非受控資源,並呼叫 GC.SuppressFinalize(this) |
Dispose(bool disposing) | 由上述兩者內部呼叫 | 類別本身 | 核心釋放邏輯:disposing=true 釋放受控+非受控;false 僅釋放非受控 |
public class BaseResource : IDisposable
{
private bool _disposed = false;
private OtherManagedResource _managed = new OtherManagedResource();
private IntPtr _unmanagedHandle = IntPtr.Zero; // 非受控資源代碼
// 1. 公開 Dispose - 供使用者呼叫
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // 通知 GC 不需再呼叫 Finalize
}
// 2. 核心虛擬方法 - 供衍生類別覆寫
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
// 釋放受控資源
_managed?.Dispose();
_managed = null;
}
// 釋放非受控資源 (無論 disposing 真偽)
if (_unmanagedHandle != IntPtr.Zero)
{
CloseHandle(_unmanagedHandle); // P/Invoke 呼叫原生 API
_unmanagedHandle = IntPtr.Zero;
}
_disposed = true;
}
// 3. 析構函式 - 防禦性最終防線
~BaseResource()
{
Dispose(false); // 僅清理非受控資源
}
// 範例:P/Invoke 宣告
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
}
public class DerivedResource : BaseResource
{
private bool _disposed = false;
private AnotherManaged _child = new AnotherManaged();
protected override void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
_child?.Dispose(); // 釋放自身受控資源
_child = null;
}
// 釋放自身非受控資源 (若有)
// ...
// 最後呼叫基底類別 Dispose
base.Dispose(disposing);
_disposed = true;
}
}
Dispose(bool) 中無論 disposing 參數皆須釋放。disposing == true 時釋放 (Finalize 階段其他受控物件可能已被回收)。_disposed 防止重複釋放;公開方法檢查並拋 ObjectDisposedException。Dispose() 中必須呼叫,避免 Finalizer 執行緒額外負擔。Dispose(bool) 並呼叫 base.Dispose(disposing)。virtual、protected,直接實作 Dispose() 即可。using (var r = new Resource()) { ... } 編譯為 try/finally 自動呼叫 Dispose()。base.Dispose(disposing) 導致基底資源洩漏。Dispose() 未呼叫 GC.SuppressFinalize。IDisposable 卻未實作 Finalize,且類別持有非受控資源。