C#中Hashtable与Dictionary的用法对比及选择
作者:AitTech
这篇文章主要介绍了C#中Hashtable与Dictionary的用法对比及选择方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
在C#中,Hashtable
与Dictionary
都是用于存储键值对的数据结构,但它们之间存在一些关键的区别。
以下是对这些区别的详细说明,并附有示例:
1. 类型安全性
Hashtable
:非泛型集合,键和值都是object
类型。这意味着在存储或检索数据时需要进行装箱和拆箱操作,可能会带来性能损耗,并且需要额外的类型转换。Dictionary
:泛型集合,可以指定键和值的类型。这提供了更好的类型安全性,因为类型是在编译时检查的,避免了运行时类型转换的错误。
示例:
// Hashtable 示例 Hashtable hashtable = new Hashtable(); hashtable.Add(1, "one"); // 键是 int 类型,值是 string 类型 hashtable.Add("key", 42); // 键是 string 类型,值是 int 类型 // 需要类型转换来检索值 string value1 = (string)hashtable[1]; int value2 = (int)hashtable["key"]; // Dictionary 示例 Dictionary<int, string> dictionary = new Dictionary<int, string>(); dictionary.Add(1, "one"); // 键和值类型明确指定 string valFromDict = dictionary[1]; // 不需要类型转换
2. 存储顺序
Hashtable
:无序集合。元素的存储顺序不是按照插入顺序的。Dictionary
:在.NET Framework 3.5及更高版本中,Dictionary
是按照插入顺序存储键值对的。这意味着遍历Dictionary
时,元素将按照它们被添加到集合中的顺序返回。
示例:
// Hashtable 无序性示例 Hashtable unorderedHashtable = new Hashtable(); unorderedHashtable.Add("a", 1); unorderedHashtable.Add("b", 2); unorderedHashtable.Add("c", 3); // 遍历顺序可能不是 "a", "b", "c" foreach (DictionaryEntry entry in unorderedHashtable) { Console.WriteLine($"{entry.Key}: {entry.Value}"); } // Dictionary 有序性示例 Dictionary<string, int> orderedDictionary = new Dictionary<string, int>(); orderedDictionary.Add("a", 1); orderedDictionary.Add("b", 2); orderedDictionary.Add("c", 3); // 遍历顺序将是 "a", "b", "c" foreach (KeyValuePair<string, int> kvp in orderedDictionary) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); }
3. 键和值的允许类型
Hashtable
:允许键和值为null
。Dictionary
:不允许键或值为null
。如果尝试添加null
键或值,将抛出ArgumentNullException
。
示例:
// Hashtable 允许 null 键和值示例 Hashtable hashtableWithNulls = new Hashtable(); hashtableWithNulls.Add(null, "nullValue"); hashtableWithNulls.Add("nullKey", null); // Dictionary 不允许 null 键和值示例 try { Dictionary<string, string> dictionaryWithNoNulls = new Dictionary<string, string>(); dictionaryWithNoNulls.Add(null, "this will throw an exception"); // 将抛出 ArgumentNullException } catch (ArgumentNullException ex) { Console.WriteLine(ex.Message); // 输出错误信息 }
4. 线程安全性
Hashtable
:是线程安全的(仅限于单线程写入,多线程读取的场景)。但性能可能受到影响,因为它需要维护线程同步。可以通过调用Synchronized()
方法获得一个线程安全的Hashtable
包装器。Dictionary
:非线程安全。在多线程环境中使用时,需要外部同步机制(如lock
语句)来保护对Dictionary
的访问。
5. 性能
Hashtable
:由于是非泛型的,且可能涉及装箱和拆箱操作,性能可能较低。Dictionary
:由于是泛型的,避免了装箱和拆箱操作,通常具有更好的性能。但在某些特定情况下(如键为字符串类型时),Hashtable
的性能可能优于Dictionary
。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。