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;
}
}
public class ResourceHolder {
private IntPtr _handle;
~ResourceHolder() { // 解構子語法 (C# 編譯為 Finalize)
ReleaseHandle(_handle);
Console.WriteLine("Finalized");
}
private void ReleaseHandle(IntPtr handle) { /* 釋放非受控資源 */ }
}
| 特性 | C++ 解構子 | C# 解構子 (Finalize) |
|---|---|---|
| 呼叫時機 | 離開作用域/刪除時確定性呼叫 | GC 非決定性呼叫 |
| 記憶體釋放 | 開發者負責 | GC 自動 |
| 例外安全 | RAII 保證 | 無保證 |
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 (var resource = new ResourceWrapper()) {
resource.DoWork();
} // 自動呼叫 Dispose()
// C# 8.0+ 範圍式
using var resource = new ResourceWrapper();
resource.DoWork();
// 區塊結束自動 Dispose
Marshal.AllocHGlobal)
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 非同步釋放建構子負責初始化,靜態建構子保證型別初始化一次。解構子 (Finalize) 是 GC 最後防線,不可依賴釋放關鍵資源。Dispose 模式是釋放非受控資源的標準方式,配合 using 確保確定性清理。SafeHandle 進一步封裝非受控控制代碼,提供更安全的抽象層。