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。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
