本文涵蓋兩大核心主題:Dictionary<TKey, TValue> 等泛型字典的正確 foreach 遍歷姿勢(KeyValuePair vs DictionaryEntry),以及泛型型別參數約束(where T : IDisposable)的基礎概念與實戰模式。
// 非泛型 Hashtable 時代寫法
foreach (DictionaryEntry de in myDict) // 編譯錯誤:無法轉換
{
Console.WriteLine(de.Key); // 需轉型
}
var dict = new Dictionary<int, string> { {1, "Foo"}, {2, "Bar"}, {3, "Baz"} };
foreach (var kvp in dict) // 隱含 KeyValuePair<int, string>
{
Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
| 面向 | DictionaryEntry (非泛型) | KeyValuePair<T,U> (泛型) |
|---|---|---|
| 鍵/值型別 | object | 強型別 TKey/TValue |
| GetEnumerator 回傳 | IEnumerator (產出 DictionaryEntry) | IEnumerator<KeyValuePair<T,U>> |
| 效能 | 需裝箱/拆箱 | 零裝箱,結構體傳值 |
| 程式碼量 | 需轉型 | 直接存取強型別屬性 |
所有實作 IDictionary<TKey, TValue> 的類別:
Dictionary<TKey, TValue>SortedList<TKey, TValue>SortedDictionary<TKey, TValue>ConcurrentDictionary<TKey, TValue>欲建立泛型集合,要求元素實作 IDisposable,以便移除時自動釋放資源。
public class DisposableList<T> : IList<T> where T : IDisposable
{
private List<T> _items = new List<T>();
private void Delete(T item) => item.Dispose(); // 安全呼叫介面方法
public void RemoveAt(int index)
{
T item = _items[index];
_items.RemoveAt(index);
Delete(item);
}
// ...
}
DisposableList<string> 報錯(string 未實作 IDisposable)DisposableList<StreamReader> 通過item.Dispose(),無需轉型或反射foreach (var kvp in dict),享受強型別、零裝箱、程式碼簡潔三重優勢。where T : Interface 讓泛型在編譯期保證型別能力,安全呼叫介面成員,是泛型程式庫設計的基石。兩者皆體現 C# 泛型系統「編譯期型別安全、執行期零成本」的核心設計哲學。