C#中Hashtable与Dictionary的用法对比及选择

 更新时间:2025年03月26日 08:40:01   作者:AitTech  
这篇文章主要介绍了C#中Hashtable与Dictionary的用法对比及选择方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在C#中,HashtableDictionary都是用于存储键值对的数据结构,但它们之间存在一些关键的区别。

以下是对这些区别的详细说明,并附有示例:

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C# 添加Word文本和图片超链接的方法

    C# 添加Word文本和图片超链接的方法

    本文给大家介绍如何用C#编程语言对Word文档中的文本和图片进行超链接设置。感兴趣的朋友一起看看吧
    2017-10-10
  • C# HangFire的使用及说明

    C# HangFire的使用及说明

    Hangfire是一个.NET后台任务处理库,支持fire-and-forget、延迟和re、周期性任务等功能,内置持久化存储和可视化监控,适用于构建高效、可靠的后台作业系统
    2026-05-05
  • C#中DataTable导出为HTML格式的方法

    C#中DataTable导出为HTML格式的方法

    在平时的开发中经常会将DataTable数据转化到页面显示、打印、导出等操作,下面这篇文章主要给大家介绍了C#中DataTable导出为HTML格式的方法,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-01-01
  • C#实现动态生成表格的方法

    C#实现动态生成表格的方法

    这篇文章主要介绍了C#实现动态生成表格的方法,是C#程序设计中非常实用的技巧,需要的朋友可以参考下
    2014-09-09
  • C#中的? 和 ??运算符使用详解

    C#中的? 和 ??运算符使用详解

    C#中的?(null条件运算符)和??(null合并运算符)用于简化null值检查和处理,?运算符在访问成员或元素前检查对象是否为null,而??运算符在左侧表达式为null时返回右侧的值,这两个运算符可以大大减少代码中的null检查样板代码,本文给大家介绍的非常详细
    2026-02-02
  • Unity实现模型点击事件的方法

    Unity实现模型点击事件的方法

    这篇文章主要介绍了Unity实现模型点击事件的方法,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • C#将配置文件appsetting中的值转换为动态对象调用

    C#将配置文件appsetting中的值转换为动态对象调用

    这篇文章主要介绍了将配置文件appsetting中的值转换为动态对象调用 ,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • C#获取系统版本信息方法

    C#获取系统版本信息方法

    今天做一个获取系统版本信息的实例,其获取方法很简单,需要的朋友可以参考下
    2012-11-11
  • 分享我在工作中遇到的多线程下导致RCW无法释放的问题

    分享我在工作中遇到的多线程下导致RCW无法释放的问题

    最近在做项目中遇到一个问题,在调用一个类库中的方法时,出现如下异常信息:尝试释放正在使用的RCW,活动线程或其他线程上正在使用该 RCW,释放正在使用的 RCW 的尝试会导致损坏或数据丢失
    2015-12-12
  • C#常用运算符的优先级示例详解

    C#常用运算符的优先级示例详解

    本文将深入探讨C#中38个常用运算符的优先级划分和理解,并提供详细的说明和示例,以帮助读者更好地理解运算符的使用,感兴趣的朋友跟随小编一起看看吧
    2025-11-11

最新评论