.NET 垃圾收集器(GC)僅管理受控記憶體。資料庫連線、檔案控制代碼、GDI 物件、COM 物件等非受控資源,必須由開發者顯式釋放。IDisposable + using 是標準模式,但巢狀 using 與異常安全常被忽略。
// 1. 原始模式:冗長、易漏寫 Close()
SqlConnection conn = new SqlConnection(cs);
conn.Open();
try { ... } finally { if (conn != null) conn.Close(); }
// 2. using 語法糖:編譯器自動展開為 try/finally
using (SqlConnection conn = new SqlConnection(cs)) {
conn.Open();
...
} // 隱含 finally { conn.Dispose(); }
// 3. 多資源巢狀 using:程式碼右移、可讀性下降
using (SqlConnection conn = new SqlConnection(cs)) {
using (SqlCommand cmd = conn.CreateCommand()) {
using (SqlDataReader dr = cmd.ExecuteReader()) { ... }
}
}
SqlConnection conn = null;
SqlDataReader dr = null;
try {
conn = new SqlConnection(cs);
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
dr = cmd.ExecuteReader();
while (dr.Read()) { ... }
}
finally {
if (dr != null) dr.Dispose();
if (conn != null) conn.Dispose();
}
優勢:扁平結構、統一錯誤處理、避免 using 隱含的 null 檢查重複(Dispose() 實作應支援多次呼叫)。
ExecuteReader() 回傳的 SqlDataReader 持有連線獨佔權。若 CommandBehavior.CloseConnection,關閉 Reader 會自動關閉連線。但在 TransactionScope 環境下,連線由交易管理,**不可**提前關閉,否則後續指令報「Connection is closed」。
IDisposable 類別**必須**遵循標準 Dispose 模式(含 Dispose(bool)、GC.SuppressFinalize)using;多資源同生命週期用單一 try/finallySafeHandle 衍生類)優於手動 IntPtr + DllImportawait using (C# 8.0+) 或 try/finally 確保 DisposeAsync 執行using 不只是語法糖,更是資源擁有權轉移的宣告。理解其展開邏輯、巢狀陷阱與交易上下文互動,才能寫出真正健壯的資源管理代碼。