C# Dictionary 从零入门:初学者必看的键值对完全指南
关键词:C# Dictionary、C# 字典、Dictionary 用法、键值对集合、.NET 新手教程

前言:为什么你一定要掌握 Dictionary?
如果你写过 C# 代码,大概率用过 List<T>。但当你需要通过某个"名字"快速找到对应的数据时,List 就开始力不从心了——你得循环遍历每一个元素,一个个比对,数据量一大,性能直接拉胯。
这时候,Dictionary<TKey, TValue>(字典)就登场了。它是 C# 中最常用、也最实用的集合类型之一,几乎所有稍微复杂一点的项目里都能看到它的身影。
这篇文章面向零基础初学者,用最通俗的语言把 Dictionary 讲透,看完你就能在实际项目里用起来。
一、Dictionary 到底是什么?
先别急着看官方定义,我们用生活中的例子来理解。
想象一本通讯录:你想找某个人的电话,不是从第一页开始一页一页翻,而是直接按名字查到对应的那一页,然后读出电话号码。
Dictionary 就是这样一本"通讯录":
- 键(Key):通讯录里的名字,比如 “张三”
- 值(Value):对应的电话号码,比如 “138xxxx1234”
- 键值对(Key-Value Pair):名字和号码是绑定在一起的一对
它的核心特点就是:通过键可以快速找到对应的值,查找时间几乎是常数级的(O(1)),不用像 List 那样从头到尾遍历。

关键特性一览
| 键唯一 | 同一个字典里不能有两个相同的键 |
| 查找快 | 通过键取值,性能接近常数时间 |
| 泛型支持 | 键和值的类型可以任意指定 |
| 允许空值 | 值可以为 null,但键不能为 null(引用类型) |
二、创建和初始化 Dictionary
2.1 最基本的创建方式
// 创建一个键为 string、值为 int 的字典
Dictionary<string, int> studentScores = new Dictionary<string, int>();
这行代码的意思是:我要建一个字典,键的类型是字符串(学生名字),值的类型是整数(考试分数)。
2.2 带初始数据的创建
Dictionary<string, int> studentScores = new Dictionary<string, int>()
{
{ "张三", 90 },
{ "李四", 85 },
{ "王五", 95 }
};
注意这个语法:每一组键值对用大括号包起来,逗号分隔。
2.3 集合初始化器(更简洁的写法)
C# 6.0 以后支持更直观的写法:
Dictionary<string, int> studentScores = new Dictionary<string, int>()
{
["张三"] = 90,
["李四"] = 85,
["王五"] = 95
};
这种写法更接近"赋值"的感觉,推荐日常使用。
三、增删改查:最常用的四个操作
这是 Dictionary 的核心,必须烂熟于心。

3.1 添加元素:Add 方法
Dictionary<string, int> scores = new Dictionary<string, int>();
// 添加一个键值对
scores.Add("赵六", 88);
// 如果键已经存在,Add 会抛出异常!
scores.Add("赵六", 99); // 运行时报错:ArgumentException
新手注意:用 Add 添加之前,一定要先确认这个键不存在,否则会直接抛异常。
更安全的写法是用索引器:
// 键不存在就添加,存在就覆盖
scores["赵六"] = 88;
3.2 获取元素:通过键取值
// 方式一:直接用索引器(键不存在会抛异常)
int score = scores["张三"];
// 方式二:TryGetValue(推荐,更安全)
if (scores.TryGetValue("张三", out int zhangsanScore))
{
Console.WriteLine($"张三的分数是:{zhangsanScore}");
}
else
{
Console.WriteLine("没找到张三的成绩");
}
强烈推荐 TryGetValue:它不会因为键不存在就崩溃,而是返回一个布尔值告诉你有没有找到。写代码的时候,安全永远比方便重要。
3.3 修改元素
修改其实和添加用的是同一个语法——索引器赋值:
// 张三考了90分,后来发现改错了,实际是95分
scores["张三"] = 95;
3.4 删除元素:Remove 方法
// 删除指定键的元素
bool removed = scores.Remove("李四");
if (removed)
{
Console.WriteLine("李四的成绩已删除");
}
else
{
Console.WriteLine("没找到李四,删不掉");
}
Remove 会返回一个 bool,表示是否真的删掉了东西。
3.5 清空整个字典
scores.Clear(); // 一键清空,啥都不剩
四、遍历 Dictionary 的几种姿势
4.1 遍历所有键值对(最常用)
foreach (KeyValuePair<string, int> item in scores)
{
Console.WriteLine($"{item.Key}:{item.Value}分");
}
4.2 只遍历键
foreach (string name in scores.Keys)
{
Console.WriteLine(name);
}
4.3 只遍历值
foreach (int score in scores.Values)
{
Console.WriteLine(score);
}
4.4 用 var 简化写法
实际项目里大家都喜欢这样写,更简洁:
foreach (var item in scores)
{
Console.WriteLine($"{item.Key}:{item.Value}分");
}
五、常用属性和方法一览
5.1 Count 属性:有多少个元素
int count = scores.Count;
Console.WriteLine($"字典里一共有 {count} 条记录");
注意:是 Count,不是 Count() 方法(那是 LINQ 的)。直接用属性更快。
5.2 ContainsKey:判断键是否存在
if (scores.ContainsKey("张三"))
{
Console.WriteLine("张三的成绩存在");
}
这个方法在添加之前做检查特别有用:
if (!scores.ContainsKey("张三"))
{
scores.Add("张三", 90);
}
5.3 ContainsValue:判断值是否存在
if (scores.ContainsValue(95))
{
Console.WriteLine("有人考了95分");
}
注意:查找值比查找键慢很多,因为值没有做哈希。能用键查就尽量用键查。
六、新手最容易踩的 5 个坑

坑 1:键重复导致 Add 抛异常
很多新手上来就 Add,结果键已经存在了,程序直接崩。
解决办法:要么先 ContainsKey 检查,要么直接用索引器赋值。
坑 2:用索引器取值,键不存在就崩
int score = scores["不存在的人"]; // 直接抛 KeyNotFoundException
解决办法:用 TryGetValue,别用裸索引器取值。
坑 3:遍历的时候修改集合
foreach (var item in scores)
{
scores.Remove(item.Key); // 运行时报错:集合已修改
}
解决办法:要删除的话,先把键存到一个临时列表里,遍历完再删:
List<string> keysToRemove = new List<string>();
foreach (var item in scores)
{
if (item.Value < 60)
{
keysToRemove.Add(item.Key);
}
}
foreach (string key in keysToRemove)
{
scores.Remove(key);
}
坑 4:用可变类型当键
比如你用一个自定义类当键,然后这个类的实例被修改了,那这个键就"找不到自己"了。
解决办法:尽量用基本类型(int、string、Guid 等)当键,稳定可靠。
坑 5:Dictionary 是无序的
很多新手以为 Dictionary 会按照添加顺序排列,其实不是。它的内部结构是哈希表,遍历顺序和插入顺序没有关系。
解决办法:如果需要按顺序遍历,用 SortedDictionary 或者遍历完自己排序。
七、Dictionary vs List:到底用哪个?

这是面试常考题,也是新手最困惑的地方。
| 查找方式 | 按键快速查找,O(1) | 遍历查找,O(n) |
| 适用场景 | 通过标识找数据 | 顺序存储一组数据 |
| 是否有序 | 无序 | 按插入顺序 |
| 内存占用 | 较大(哈希表结构) | 较小 |
| 典型例子 | 用户名→用户信息 | 商品列表 |
简单记:
- 需要按名字快速找东西 → 用 Dictionary
- 需要按顺序排一排 → 用 List
- 两者经常配合使用,不是二选一的关系
八、实战小例子:学生成绩管理系统
光说不练假把式,我们来写一个完整的小例子,把前面学的都串起来。
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// 创建成绩字典
Dictionary<string, int> scores = new Dictionary<string, int>()
{
["张三"] = 90,
["李四"] = 85,
["王五"] = 95,
["赵六"] = 58
};
Console.WriteLine("=== 学生成绩管理系统 ===");
// 1. 查询某个学生的成绩
Console.Write("请输入要查询的学生姓名:");
string name = Console.ReadLine();
if (scores.TryGetValue(name, out int score))
{
Console.WriteLine($"{name} 的成绩是:{score} 分");
}
else
{
Console.WriteLine($"没找到 {name} 的成绩");
}
// 2. 统计有多少人不及格
int failCount = 0;
List<string> failNames = new List<string>();
foreach (var item in scores)
{
if (item.Value < 60)
{
failCount++;
failNames.Add(item.Key);
}
}
Console.WriteLine($"\\n不及格的同学有 {failCount} 人:");
foreach (string failName in failNames)
{
Console.WriteLine($" – {failName}");
}
// 3. 计算平均分
int total = 0;
foreach (int s in scores.Values)
{
total += s;
}
double avg = (double)total / scores.Count;
Console.WriteLine($"\\n班级平均分:{avg:F2} 分");
}
}
这个例子虽然简单,但涵盖了创建、查询、遍历、统计等核心操作,你可以直接拿去跑一遍,感受一下。
九、总结
到这里,Dictionary 的核心知识点就讲完了。我们来快速回顾一下:
Dictionary 是 C# 集合里最基础也最常用的类型之一,把它掌握好,后面学更复杂的集合(比如 ConcurrentDictionary)也会轻松很多。
如果这篇文章对你有帮助,欢迎点赞收藏,有问题可以在评论区留言交流。
标签:C#、Dictionary、.NET、新手教程、键值对集合、编程入门
网硕互联帮助中心




评论前必须登录!
注册