.NET 2.0 引入 Dictionary<TKey, TValue> 取代非泛型 Hashtable,帶來型別安全、效能提升(避免裝箱/拆箱)、語意清晰等優勢。但兩者 API 不完全對等,遷移時需處理成員差異、缺失功能補齊。本文提供完整對照表與程式碼範例,助你無痛遷移。
| Hashtable 成員 | Dictionary 對應成員 | 備註 |
|---|---|---|
| Count | Count | 完全相同 |
| Keys | Keys | 回傳 ICollection<TKey> vs ICollection |
| Values | Values | 回傳 ICollection<TValue> vs ICollection |
| Item[key] | Item[key] | 型別安全,無需轉型 |
| Add | Add | 參數型別強類型 |
| Clear | Clear | 相同 |
| Contains(key) | ContainsKey(key) | Hashtable 的 Contains 等同 ContainsKey |
| ContainsKey | ContainsKey | 相同 |
| ContainsValue | ContainsValue | 相同 |
| Remove | Remove | 相同 |
| Clone | 建構子 new Dictionary(dict) | Dictionary 未實作 ICloneable |
| CopyTo(Array, index) | ((ICollection)dict).CopyTo(arr, index) | 需轉型為 ICollection |
| IsFixedSize | ((IDictionary)dict).IsFixedSize | 需轉型為 IDictionary |
| IsReadOnly | ((IDictionary)dict).IsReadOnly | 需轉型為 IDictionary |
| IsSynchronized | ((IDictionary)dict).IsSynchronized | 永遠回傳 false |
| SyncRoot | ((IDictionary)dict).SyncRoot | 回傳 this,建議改用 lock |
| Synchronized() | 無對應 | 改用 lock(dict.SyncRoot) 或專用同步物件 |
| - | TryGetValue | Dictionary 獨有,高效鍵值原子讀取 |
| - | Comparer | Dictionary 獨有,取得比較器 |
var numbers = new Dictionary<int, string>();
Console.WriteLine(((IDictionary)numbers).IsReadOnly);
Console.WriteLine(((IDictionary)numbers).IsFixedSize);
Console.WriteLine(((IDictionary)numbers).IsSynchronized); // 永遠 false
Console.WriteLine(((IDictionary)numbers).SyncRoot); // 回傳 this
注意:IsSynchronized 永遠為 false,Microsoft 移除了泛型集合的同步包裝功能,建議改用 lock 手動同步。
var numbers = new Dictionary<int, string> { {1, "one"}, {2, "two"} };
var clonedNumbers = new Dictionary<int, string>(numbers); // 建構子複製
bool exists = numbers.ContainsKey(1); // 直接使用
var objs = new KeyValuePair<int, string>[numbers.Count];
((ICollection)numbers).CopyTo(objs, 0);
foreach (var kvp in objs)
Console.WriteLine($"Key: {kvp.Key}\tValue: {kvp.Value}");
關鍵點:建立 KeyValuePair<TKey, TValue>[] 陣列,轉型 ICollection 呼叫 CopyTo。
Hashtable → Dictionary<TKey, TValue>,補齊型別參數。DictionaryEntry → KeyValuePair<TKey, TValue>。(int)de.Key 等轉型。ToDictionary() (LINQ)。Hashtable.Synchronized,改用 lock(_syncObj) 包裝操作。ContainsKey + Item[key] 兩次查找。Dictionary 可序列化,但自訂比較器需標記 [Serializable]。Dictionary<int, T> 完全避免裝箱,效能碾壓 Hashtable。Dictionary 仍具型別安全優勢。Dictionary 結構更緊湊(無 DictionaryEntry 物件)。Hashtable 到 Dictionary 的遷移是 .NET 現代化的必經之路。掌握成員對照表、補齊缺失功能、建立遷移檢查清單,即可安全、高效完成遷移。新專案請直接使用 Dictionary<TKey, TValue> 或 ConcurrentDictionary(多執行緒場景),勿再使用 Hashtable。