讲师中心 微信公众号
AI工具推荐 视频效率加速

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

老明吖_1629

老明吖_1629

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

|

551人浏览过

|

来源于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,容易漏掉空引用异常
  • ContainsKey 和 ContainsValue 都是 O(n) 查找(因为 value 未索引),大数据量时很慢
  • 键为 null 是允许的(仅一个),但值为 null 完全没问题 —— 这和 Dictionary 对 null 键的严格限制完全不同

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

关键瓶颈在值类型操作:int、bool、DateTime 等作为键或值时,Hashtable 必然触发装箱(boxing),而 Dictionary<int string></int> 完全避免。

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

下载
  • 实测:10 万次插入 int→string,Dictionary 比 Hashtable 快 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<tkey tvalue></tkey>,它针对读多写少做了精细分段锁,比包装后的 Hashtable 实际吞吐更高
  • 注意:Hashtable 的“线程安全”仅限于 .NET Framework;.NET Core 中 Synchronized() 方法已移除,调用即抛 PlatformNotSupportedException

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

热门AI工具

更多
小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

讯飞智文

一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
string转int
string转int

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

7239

2023.08.02

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

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

549

2023.09.22

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

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

1698

2024.03.01

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

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

549

2023.09.22

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

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

1698

2024.03.01

string转int
string转int

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

7239

2023.08.02

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

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

3445

2024.08.29

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

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

4528

2025.08.29

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

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

精品课程

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn