0

0

C# 哈希表Hashtable使用方法 C# Hashtable和Dictionary的区别

煙雲

煙雲

发布时间:2026-02-04 08:08:02

|

491人浏览过

|

来源于php中文网

原创

应优先使用 Dictionary,仅在维护老旧 .NET Framework 1.x/2.0 代码或需运行时混存多种键类型时才用 Hashtable;后者存在装箱开销、O(n) 查找、伪线程安全及遍历无序等缺陷。

c# 哈希表hashtable使用方法 c# hashtable和dictionary的区别

什么时候该用 Hashtable,而不是 Dictionary

绝大多数新项目里,Hashtable 已不是首选。它只在两类场景下仍有实际价值:
一是维护非常老的 .NET Framework 1.x/2.0 代码,且升级成本过高;二是需要运行时动态混存多种键类型(比如同一集合里同时存 int 键、string 键、Guid 键),且明确接受类型不安全和性能损耗。

  • Hashtable 允许 hashtable.Add(1, "a")hashtable.Add("key", DateTime.Now) 混用,Dictionary 编译直接报错
  • 但代价是:每次取值都要强制转型,比如 (string)hashtable[1],一旦类型写错,程序在运行时才崩
  • .NET Core / .NET 5+ 中 Hashtable 已被标记为“遗留类型”,官方文档明确建议迁移到 Dictionary 或线程安全的 ConcurrentDictionary

Hashtable 的基本用法和典型陷阱

初始化后,所有键值都以 object 存储,遍历时必须用 DictionaryEntry,不能直接解构:

Hashtable ht = new Hashtable();
ht.Add("name", "Alice");
ht.Add(42, true);

// ✅ 正确遍历方式
foreach (DictionaryEntry entry in ht)
{
    Console.WriteLine($"{entry.Key} → {entry.Value}");
}

// ❌ 错误:不能直接 foreach (var kv in ht)
// ❌ 错误:ht["missing"] 返回 null,不是抛异常 —— 容易掩盖逻辑错误
  • 访问不存在的键(如 ht["xxx"])返回 null,不会抛 KeyNotFoundException,容易漏掉空引用异常
  • ContainsKeyContainsValue 都是 O(n) 查找(因为 value 未索引),大数据量时很慢
  • 键为 null 是允许的(仅一个),但值为 null 完全没问题 —— 这和 Dictionary 对 null 键的严格限制完全不同

性能差异到底差在哪?不只是“泛型 vs 非泛型”

关键瓶颈在值类型操作:intboolDateTime 等作为键或值时,Hashtable 必然触发装箱(boxing),而 Dictionary 完全避免。

Presentations.AI
Presentations.AI

AI驱动创建令人惊叹的演示文稿

下载
  • 实测:10 万次插入 int→stringDictionaryHashtable 快 2–3 倍(.NET 6 环境)
  • Hashtable 内部每个节点是 DictionaryEntry 对象,堆分配频繁,GC 压力大;Dictionary 用紧凑数组 + 索引管理,缓存友好
  • 哈希冲突处理上,Dictionary 在 .NET Core 2.1+ 中链表长度 >8 自动转红黑树,最坏查找从 O(n) 降到 O(log n);Hashtable 始终是链表,无此优化

线程安全别被“文档误导”

文档说 Hashtable.Synchronized() 是线程安全的,但实际是“伪安全”——它只保证单个方法原子性(如单次 Add 不会中断),不保证多步操作的事务性。例如“检查是否存在再添加”这种常见模式依然会出错:

var syncHt = Hashtable.Synchronized(new Hashtable());
if (!syncHt.ContainsKey("x")) {
    syncHt.Add("x", "val"); // ❌ 仍可能并发重复添加!
  • Dictionary 默认完全不加锁,多线程写必须自己用 lock 包裹整段逻辑,性能损失明显
  • 真要线程安全,应直接用 ConcurrentDictionary,它针对读多写少做了精细分段锁,比包装后的 Hashtable 实际吞吐更高
  • 注意:Hashtable 的“线程安全”仅限于 .NET Framework;.NET Core 中 Synchronized() 方法已移除,调用即抛 PlatformNotSupportedException

真正容易被忽略的是:Hashtable 的无序性不是“偶尔乱”,而是完全不可预测——哪怕插入顺序固定,不同 .NET 版本、不同 CPU 架构下遍历结果都可能不同;而 Dictionary 自 .NET Framework 3.5 起就稳定保持插入顺序,这对调试和日志可重现性至关重要。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

543

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

238

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

539

2024.03.01

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

238

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

539

2024.03.01

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

543

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

547

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

153

2025.08.29

全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

19

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 5.1万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.4万人学习

Django 教程
Django 教程

共28课时 | 3.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号