news 2026/2/16 9:27:06

C#之字典

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#之字典

C# 字典(Dictionary)教程:从基础到高级应用

字典(Dictionary)是C#中最常用的集合类型之一,它存储键值对(Key-Value Pair)并提供高效的查找功能。本教程将全面介绍C#中字典的使用方法,包括基本操作、高级特性和实际应用场景。

1. 字典的基本概念

字典是一种关联集合,具有以下特点:

  • 键值对存储:每个元素由一个唯一的键(Key)和一个关联的值(Value)组成
  • 快速查找:通过键可以快速访问对应的值,平均时间复杂度为O(1)
  • 唯一键:字典中的键必须是唯一的,不能重复
  • 无序性:.NET中的字典不保证元素的顺序(虽然.NET Core 3.0+提供了有序字典)

2. 创建字典

2.1 基本创建方式

usingSystem;usingSystem.Collections.Generic;classProgram{staticvoidMain(){// 创建空字典(非泛型,不推荐)Dictionarydictionary=newDictionary();// 创建泛型字典(推荐)Dictionary<string,int>ageDictionary=newDictionary<string,int>();// 使用集合初始化器Dictionary<string,string>capitalDictionary=newDictionary<string,string>{{"China","Beijing"},{"USA","Washington D.C."},{"Japan","Tokyo"}};}}

推荐使用泛型版本Dictionary<TKey, TValue>,它提供了类型安全性和更好的性能。

2.2 指定比较器

可以自定义键的比较方式:

// 不区分大小写的字符串比较器Dictionary<string,int>caseInsensitiveDict=newDictionary<string,int>(StringComparer.OrdinalIgnoreCase);caseInsensitiveDict.Add("apple",1);Console.WriteLine(caseInsensitiveDict["APPLE"]);// 输出1

3. 基本操作

3.1 添加元素(Add)

Dictionary<string,int>scores=newDictionary<string,int>();scores.Add("Alice",90);scores.Add("Bob",85);// 尝试添加重复键会抛出异常try{scores.Add("Alice",95);// 抛出ArgumentException}catch(Exceptionex){Console.WriteLine($"错误:{ex.Message}");}

3.2 安全添加元素

使用索引器或TryAdd(需要.NET 6+)可以避免异常:

// 方法1: 使用索引器(如果键存在则更新值)scores["Alice"]=95;// 更新Alice的分数// 方法2: 使用TryAdd(.NET 6+)booladded=scores.TryAdd("Charlie",88);// 返回true表示添加成功

3.3 访问元素

// 通过键访问值intaliceScore=scores["Alice"];// 如果键不存在会抛出KeyNotFoundException// 安全访问方式if(scores.TryGetValue("Bob",outintbobScore)){Console.WriteLine($"Bob的分数是:{bobScore}");}else{Console.WriteLine("未找到Bob的分数");}

3.4 检查键是否存在

boolhasAlice=scores.ContainsKey("Alice");// trueboolhasDavid=scores.ContainsKey("David");// false

3.5 检查值是否存在

boolhas90=scores.ContainsValue(90);// true

3.6 移除元素

// 方法1: 通过键移除boolremoved=scores.Remove("Bob");// 返回true表示成功移除// 方法2: 通过键值对移除(.NET 6+)boolremoved2=scores.Remove(newKeyValuePair<string,int>("Alice",95));

3.7 清空字典

scores.Clear();Console.WriteLine($"字典中现在有{scores.Count}个元素");// 输出0

4. 完整示例

usingSystem;usingSystem.Collections.Generic;classDictionaryExample{staticvoidMain(){// 创建并初始化字典Dictionary<string,double>productPrices=newDictionary<string,double>{{"Apple",1.20},{"Banana",0.50},{"Orange",0.80}};// 添加新元素productPrices.Add("Pear",1.00);// 更新元素productPrices["Apple"]=1.50;// 安全获取元素if(productPrices.TryGetValue("Banana",outdoublebananaPrice)){Console.WriteLine($"香蕉的价格是: ${bananaPrice:F2}");}// 遍历字典Console.WriteLine("\n所有产品价格:");foreach(KeyValuePair<string,double>productinproductPrices){Console.WriteLine($"{product.Key}: ${product.Value:F2}");}// 移除元素productPrices.Remove("Orange");Console.WriteLine($"\n移除后字典中有{productPrices.Count}个产品");}}

5. 高级用法

5.1 遍历字典

Dictionary<int,string>employees=newDictionary<int,string>{{101,"Alice"},{102,"Bob"},{103,"Charlie"}};// 遍历键值对foreach(KeyValuePair<int,string>employeeinemployees){Console.WriteLine($"ID:{employee.Key}, 姓名:{employee.Value}");}// 只遍历键foreach(intidinemployees.Keys){Console.WriteLine($"ID:{id}");}// 只遍历值foreach(stringnameinemployees.Values){Console.WriteLine($"姓名:{name}");}

5.2 字典排序

字典本身是无序的,但可以转换为有序集合:

// 按键排序Dictionary<string,int>unsortedDict=newDictionary<string,int>{{"Zebra",5},{"Apple",1},{"Banana",2}};// 按键排序并创建新字典SortedDictionary<string,int>sortedByKey=newSortedDictionary<string,int>(unsortedDict);// 按值排序(需要LINQ)varsortedByValue=unsortedDict.OrderBy(x=>x.Value).ToDictionary(x=>x.Key,x=>x.Value);

5.3 字典并发操作

在多线程环境中,可以使用ConcurrentDictionary<TKey, TValue>

usingSystem.Collections.Concurrent;ConcurrentDictionary<string,int>concurrentDict=newConcurrentDictionary<string,int>();// 线程安全添加concurrentDict.TryAdd("Key1",100);// 线程安全更新concurrentDict.AddOrUpdate("Key1",key=>200,// 如果键不存在时的添加值(key,oldValue)=>oldValue+50);// 如果键存在时的更新逻辑// 线程安全获取或添加intvalue=concurrentDict.GetOrAdd("Key2",key=>300);

5.4 字典与数组/列表转换

Dictionary<string,int>dict=newDictionary<string,int>{{"a",1},{"b",2},{"c",3}};// 转换为键数组string[]keys=dict.Keys.ToArray();// 转换为值数组int[]values=dict.Values.ToArray();// 从两个列表创建字典List<string>names=newList<string>{"Alice","Bob","Charlie"};List<int>ids=newList<int>{101,102,103};Dictionary<int,string>idToNameDict=names.Select((name,index)=>new{name,index}).ToDictionary(x=>ids[x.index],x=>x.name);

6. 实际应用场景

6.1 缓存实现

publicclassSimpleCache<TKey,TValue>{privatereadonlyDictionary<TKey,TValue>cache=newDictionary<TKey,TValue>();privatereadonlyTimeSpanexpirationTime;privatereadonlyDictionary<TKey,DateTime>expirationTimes=newDictionary<TKey,DateTime>();publicSimpleCache(TimeSpanexpirationTime){this.expirationTime=expirationTime;}publicvoidAdd(TKeykey,TValuevalue){cache[key]=value;expirationTimes[key]=DateTime.Now.Add(expirationTime);}publicboolTryGetValue(TKeykey,outTValuevalue){if(cache.TryGetValue(key,outvalue)){if(expirationTimes.TryGetValue(key,outDateTimeexpiration)&&DateTime.Now<expiration){returntrue;}else{cache.Remove(key);expirationTimes.Remove(key);returnfalse;}}returnfalse;}}

6.2 统计词频

stringtext="hello world hello csharp world hello";string[]words=text.Split(new[]{' '},StringSplitOptions.RemoveEmptyEntries);Dictionary<string,int>wordCounts=newDictionary<string,int>();foreach(stringwordinwords){if(wordCounts.ContainsKey(word)){wordCounts[word]++;}else{wordCounts[word]=1;}}// 使用LINQ更简洁的实现varwordCountsLinq=words.GroupBy(w=>w).ToDictionary(g=>g.Key,g=>g.Count());

6.3 配置管理

publicclassConfigurationManager{privatereadonlyDictionary<string,string>settings=newDictionary<string,string>{{"Server","localhost"},{"Port","8080"},{"Timeout","30"}};publicstringGetSetting(stringkey,stringdefaultValue=""){returnsettings.TryGetValue(key,outstringvalue)?value:defaultValue;}publicvoidSetSetting(stringkey,stringvalue){settings[key]=value;}}

7. 性能考虑

  • 查找性能:字典的查找、添加和删除操作的平均时间复杂度为O(1)
  • 哈希冲突:当多个键产生相同的哈希码时会影响性能,良好的键类型选择很重要
  • 容量规划:字典在容量不足时会自动扩容,可以预先指定容量减少扩容次数
    Dictionary<int,string>dict=newDictionary<int,string>(capacity:1000);
  • 键类型选择:优先选择值类型或不可变引用类型作为键,避免使用可变对象作为键

8. 与类似集合的比较

集合类型特点
Dictionary<TKey, TValue>键值对集合,快速查找,键唯一
SortedDictionary<TKey, TValue>基于红黑树实现,按键排序,查找O(log n)
SortedList<TKey, TValue>按键排序的键值对集合,值也按键排序,查找O(log n),插入删除性能较差
ConcurrentDictionary<TKey, TValue>线程安全的字典,适合多线程环境
Lookup<TKey, TElement>表示一个键到多个值的映射,键唯一但值不唯一

总结

C#中的字典(Dictionary<TKey, TValue>)是一种强大且高效的数据结构,适用于需要快速查找和关联存储的场景。通过本教程,你应该已经掌握了:

  • 字典的基本概念和创建方式
  • 字典的增删改查操作
  • 字典的高级特性和并发处理
  • 字典的实际应用场景
  • 字典与其他类似集合的区别
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/6 20:34:38

Yolov5在HeyGem中用于人脸检测的技术可能性探讨

Yolov5在HeyGem中用于人脸检测的技术可能性探讨 在数字人视频生成系统日益普及的今天&#xff0c;如何让虚拟人物的口型与语音完美同步&#xff0c;成为决定用户体验的关键。而这一切的前提&#xff0c;是系统能否稳定、准确地“看到”原始视频中的人脸——这正是人脸检测技术的…

作者头像 李华
网站建设 2026/2/12 8:44:12

【C#不安全类型转换实战指南】:揭秘高效内存操作的5大核心技巧

第一章&#xff1a;C#不安全类型转换概述在C#编程中&#xff0c;类型系统是保障内存安全和代码稳定的核心机制。然而&#xff0c;在某些特定场景下&#xff0c;开发者可能需要绕过CLR的类型检查&#xff0c;执行不安全的类型转换。这类操作通常涉及指针、未托管内存或跨类型的直…

作者头像 李华
网站建设 2026/2/6 20:33:21

以下从技术架构剖析的真实案例切入,再给出分阶段的学习路线规划,兼顾理论与落地,帮助你高效掌握架构设计能力

以下从技术架构剖析的真实案例切入&#xff0c;再给出分阶段的学习路线规划&#xff0c;兼顾理论与落地&#xff0c;帮助你高效掌握架构设计能力。一、技术架构剖析&#xff1a;2个真实案例 案例1&#xff1a;某电商平台大促订单系统&#xff08;高并发场景&#xff09; 背景&a…

作者头像 李华
网站建设 2026/2/7 8:08:41

【C#集合表达式终极指南】:5分钟掌握数组高效操作核心技术

第一章&#xff1a;C#集合表达式与数组概述 C# 作为一门强类型、面向对象的编程语言&#xff0c;提供了丰富的数据结构支持&#xff0c;其中数组和集合表达式是处理数据序列的核心工具。从 C# 1.0 开始&#xff0c;数组一直是存储固定大小同类型元素的基础方式&#xff1b;而随…

作者头像 李华
网站建设 2026/2/15 15:32:09

Span与unsafe代码共存时的内存防护策略,资深架构师绝不外传的4条铁律

第一章&#xff1a;Span与unsafe代码共存时的内存防护策略&#xff0c;资深架构师绝不外传的4条铁律 在高性能 .NET 应用开发中&#xff0c;Span 与 unsafe 代码常被结合使用以实现零拷贝、高吞吐的数据处理。然而&#xff0c;这种组合也带来了显著的内存安全风险。以下是资深架…

作者头像 李华