using 關鍵字有兩種用法:
using System.IO;using (var res = new Resource()) { ... } —— 本文主角。
public class Demo : IDisposable
{
public void Dispose()
{
Console.WriteLine("Dispose 被呼叫,釋放非受控資源");
}
public void DoWork() => Console.WriteLine("執行工作");
}
// 寫法
using (var d = new Demo())
{
d.DoWork();
}
// 編譯器展開為
Demo d = new Demo();
try
{
d.DoWork();
}
finally
{
if (d != null)
((IDisposable)d).Dispose(); // 保證釋放
}
// 傳統寫法:易忘記 Close,例外時洩漏
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
// ...
conn.Close();
// using 寫法:自動釋放,例外安全
using (var conn = new SqlConnection(connStr))
{
conn.Open();
using (var cmd = new SqlCommand(sql, conn))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read()) { /* ... */ }
}
} // 此處自動呼叫 conn.Dispose() -> Close()
// C# 8+ 可簡化為單一 using 陳述式
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(sql, conn))
using (var reader = cmd.ExecuteReader())
{
// ...
}
// 或更簡潔
using var conn = new SqlConnection(connStr);
using var cmd = new SqlCommand(sql, conn);
// 範圍結束自動 Dispose
| 命名空間 | 類別 | 資源類型 |
|---|---|---|
| System.IO | Stream, FileStream, StreamReader/Writer, BinaryReader/Writer | 檔案控制碼 |
| System.Data | SqlConnection, SqlCommand, SqlDataReader, DbTransaction | 資料庫連線、交易 |
| System.Net | HttpWebResponse, WebResponse, HttpClient (需 .NET Core 2.1+) | 網路連線 |
| System.Drawing | Bitmap, Graphics, Pen, Brush, Font | GDI+ 物件 |
| System.Threading | Mutex, Semaphore, EventWaitHandle | 核心同步物件 |
| System.Security.Cryptography | HashAlgorithm, SymmetricAlgorithm, X509Certificate2 | 加密控制碼 |
public class ResourceHolder : IDisposable
{
private IntPtr _handle; // 非受控資源
private bool _disposed;
public ResourceHolder()
{
_handle = NativeMethods.AcquireResource();
}
// 公開 Dispose
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // 告訴 GC 不需呼叫 Finalizer
}
// 核心邏輯:disposing=true 來自 Dispose(),false 來自 Finalizer
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
// 釋放受控資源
}
// 釋放非受控資源
if (_handle != IntPtr.Zero)
{
NativeMethods.ReleaseResource(_handle);
_handle = IntPtr.Zero;
}
_disposed = true;
}
// Finalizer:防止使用者忘記 Dispose
~ResourceHolder()
{
Dispose(false);
}
}
using 陳述式是 C# 資源管理的基石,將 try/finally 模板化、強制化。凡實作 IDisposable 的物件,請無腦套用 using。這不只是編碼習慣,更是對系統資源負責的專業態度。