C#中键值对类型Hashtable与Dictionary比较和相关用法

本文对比了C#中的Dictionary与Hashtable两种键值对容器的不同之处,包括数据结构、线程安全性、类型安全性和效率等方面,并介绍了Dictionary的常用操作。
最近在使用C#中的Hashtable与Dictionary的时候,想知道其区别,通过查找网络相关博客资料,作出下列总结。
Hashtable与Dictionary虽然都是作为键值对的载体,但是采用的是不同的数据结构。就像Java中的ArrayList与LinkList,虽然都是实现了List接口作为集合载体,但是其内部结构是不一样的,ArrayList是通过数组实现的,LinkList是通过对象链表实现的。


由于 Hashtable 和 Dictionary 同时存在, 在使用场景上必然存在选择性, 并不任何时刻都能相互替代.
[1] 单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.
[2] 多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.
[3] Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便.


个人偏向于使用Dictionary,因为其使用泛型,可控性比较强。在一些资料中,很多人也推荐使用Dictionary,其原因主要有
1、Dic是类型安全的,这有助于我们写出更健壮更具可读性的代码,而且省却我们强制转化的麻烦。
2、Dic是泛行的,当K或V是值类型时,其速度远远超过Hashtable。处理对象时不需要进行显式或是隐式转型,进行值类型处理时不需要装箱。所以使用方便一些,而且效率会高一些(编码效率、运行效率),还不太容易出错。


Dictionary 调用 Add 方法之前使用 ContainsKey 方法测试某个键是否存在,否则得到一个KeyNotFoundException。当程序频繁尝试字典中不存在的键时,使用 TryGetValue 方法来检索值,这种方法是一种更有效的检索值的方法。


下面是对于Dictionary的一些常用的操作,包括遍历,添加,删除等


Dictionary<int, string> dictionary = new Dictionary<int, string>();    
dictionary.Add(1, "xiaowang");    
dictionary.Add(21, "dsd");    
dictionary.Add(33, "dsfdfd");    
dictionary.Add(4, "liusang");     
    
foreach (KeyValuePair<int, string> kvp in dictionary)    
{    
    Console.WriteLine("key={0},value={1}", kvp.Key, kvp.Value);    
}     
    
foreach (int j in dictionary.Keys)    
{    
    Console.WriteLine("key={0},value={1}", j, dictionary[j]);    
}     
if (dictionary.ContainsKey(2))       
{       
    Console.WriteLine(dict[2]);       
 }       
 //遍历Keys       
foreach (var item in dictionary.Keys)  
{       
    Console.WriteLine("Key:{0}", item);       
}       
 //遍历Values       
foreach (var item in dictionary.Values)       
{       
   Console.WriteLine("value:{0}", item);       
}       



<think>好的,用户想了解在C#中如何使用键值对。首先,我需要回顾一下C#中常用的键值对结构,比如DictionaryHashtable,还有如何读写配置文件中的键值对。根据提供的引用,用户已经提到了这些内容,所以需要系统地整理这些信息。 首先,Dictionary<TKey, TValue>是泛型类型类型安全,性能较好。需要展示如何创建、添加、访问遍历字典。例如引用[1]中的示例,可以详细说明每个步骤,并强调键的唯一性。同时,要提到ContainsKey方法的使用,避免重复添加导致的异常。 接下来是Hashtable,它是非泛型的,存储Object类型,可能存在装箱拆箱的问题。引用[2]中的例子展示了Add方法、通过键赋、ContainsKey检查以及遍历。需要注意的是HashtableDictionary的区别,比如线程安全性性能差异,这里可能需要简要比较两者的适用场景。 然后是配置文件的读写,引用[3]中使用ConfigurationManager来读取修改App.config中的键。需要说明添加配置节点的方法,以及如何保存修改后的配置。这部分需要注意权限问题,因为修改配置文件可能需要应用程序有足够的权限。 用户可能还关心实际应用中的注意事项,比如异常处理、线程安全,或者如何选择合适的数据结构。例如,Dictionary在单线程环境下更高效,而Hashtable是线程安全的。此外,配置文件的修改可能需要重启应用才能生效,或者使用ConfigurationManager.RefreshSection来刷新配置。 需要确保示例代码正确,比如检查Add方法的键是否存在,避免运行时错误。同时,强调键值对在不同场景下的应用,比如缓存、配置管理、数据存储等。可能还需要提到其他结构,比如ConcurrentDictionary用于多线程环境。 最后,生成相关问题时要覆盖主要知识点,比如区别、选择原因、配置文件操作实际应用场景,帮助用户进一步学习。</think>在C#中,键值对的使用主要通过三种典型方式实现,以下是具体方法及示例: ### 一、Dictionary<TKey, TValue>基础用法 ```csharp // 创建字典 Dictionary<string, int> fruits = new Dictionary<string, int>(); // 添加键值对 fruits.Add("apple", 5); fruits.Add("orange", 8); // 安全添加(避免重复键) if(!fruits.ContainsKey("banana")) { fruits["banana"] = 3; // 使用索引器添加 } // 遍历字典 foreach(KeyValuePair<string, int> item in fruits) { Console.WriteLine($"{item.Key}: {item.Value}"); } ``` *特点*:类型安全、高性能,适合大多数键存储场景[^1] ### 二、Hashtable使用示例 ```csharp Hashtable ht = new Hashtable(); ht.Add(1, "张三"); ht["dynamicKey"] = DateTime.Now; // 动态添加 // 安全移除 if(ht.ContainsKey(3)) { ht.Remove(3); } // 遍历键值对 foreach(DictionaryEntry entry in ht) { Console.WriteLine($"Key:{entry.Key} Value:{entry.Value}"); } ``` *注意*:支持任意类型,但需要类型转换,存在装箱/拆箱性能损耗[^2] ### 三、配置文件操作 1. 在App.config中添加配置节: ```xml <configuration> <appSettings> <add key="MaxConnections" value="50"/> </appSettings> </configuration> ``` 2. 读写配置: ```csharp // 读取配置 string maxConn = ConfigurationManager.AppSettings["MaxConnections"]; // 修改配置 Configuration config = ConfigurationManager.OpenExeConfiguration(...); config.AppSettings.Settings["MaxConnections"].Value = "100"; config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("appSettings"); // 强制刷新 ``` *注意*:修改后需调用RefreshSection使内存中的配置更新[^3] 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值