using 是 C# 中最常見卻常被誤解的關鍵字,實際上有三種截然不同的用途:引入命名空間、建立型別別名、定義資源釋放範圍。本文逐一說明語法、適用場景與最佳實踐。
using System; // 引入整個命名空間
using System.Collections.Generic;
// 兩個命名空間皆有 Console 類別
System.Console.WriteLine("Hello"); // 明確指定
MyNamespace.Console.DoSomething();
using Zip = System.IO.Compression; // 命名空間別名
using GZip = System.IO.Compression.GZipStream; // 型別別名
// 使用
var stream = new GZip();
using System;
using AClass = NameSpace1.MyClass;
using BClass = NameSpace2.MyClass;
namespace NameSpace1 { public class MyClass { public override string ToString() => "NameSpace1"; } }
namespace NameSpace2 { public class MyClass { public override string ToString() => "NameSpace2"; } }
class Program {
static void Main() {
AClass a = new AClass();
BClass b = new BClass();
Console.WriteLine(a); // NameSpace1
Console.WriteLine(b); // NameSpace2
}
}
注意:若兩個同名型別皆需使用,兩者都必須定義別名,否則編譯器仍無法辨識。
using (var resource = new MyResource()) {
// 使用 resource
} // 離開區塊自動呼叫 resource.Dispose()
MyResource resource = new MyResource();
try {
// 使用 resource
}
finally {
if (resource != null) resource.Dispose();
}
using (var fs = File.OpenRead("a.txt"))
using (var sr = new StreamReader(fs)) {
Console.WriteLine(sr.ReadToEnd());
}
IDisposable 的物件:檔案流、資料庫連線、圖形物件、網路連線等。| 錯誤寫法 | 問題 | 正確做法 |
|---|---|---|
using (var x = GetObj()) { } 但 GetObj() 回傳非 IDisposable | 編譯錯誤 | 確認型別實作 IDisposable |
在 using 區塊外使用已釋放物件 | ObjectDisposedException | 所有操作置於區塊內 |
以為 using 能管理記憶體 | 僅釋放非受控資源,記憶體仍由 GC 管理 | 理解 Dispose 與 Finalize 差異 |
using namespace:簡化型別名稱,注意衝突。using Alias = Type:解決同名型別衝突,雙方皆需別名。using (var r = ...):確保 IDisposable 物件正確釋放,優於手動 try/finally。