# Dictionary 概念: `Dictionary` 是 C# 提供的==泛型键值对集合== 它通过键 `key` 来快速查找值 `value` 简单理解: 像一本字典 用“词”查“解释” 用 `key` 查 `value` 命名空间: ```csharp using System.Collections.Generic; ``` ---- # 通常用法 1. 保存键值对数据 2. 通过唯一键快速查找对应值 3. 根据 `id`、名字、编号等信息管理对象 4. 替代早期非泛型键值对集合 `Hashtable` 实际开发中: `Dictionary` 非常常用 只要需求是“通过 key 快速找到 value” 通常都可以先考虑它 ---- # 语法 创建: ```csharp Dictionary dict = new Dictionary(); ``` 添加: ```csharp dict.Add("语文", 90); ``` 通过键取值: ```csharp int score = dict["语文"]; ``` 修改: ```csharp dict["语文"] = 95; ``` 数量: ```csharp dict.Count ``` ---- # 基础案例 ```csharp using System; using System.Collections.Generic; Dictionary scores = new Dictionary(); scores.Add("语文", 90); scores.Add("数学", 95); scores.Add("英语", 88); Console.WriteLine(scores["语文"]); Console.WriteLine(scores["数学"]); Console.WriteLine(scores["英语"]); Console.WriteLine(scores.Count); ``` 输出: ```text 90 95 88 3 ``` 理解: 1. `"语文"`、`"数学"`、`"英语"` 是键 2. `90`、`95`、`88` 是值 3. 通过 key 能快速找到对应 value ---- # Add 和索引器 使用 `Add` 添加: ```csharp Dictionary dict = new Dictionary(); dict.Add("hp", 100); dict.Add("mp", 50); ``` 使用索引器新增或修改: ```csharp dict["atk"] = 20; // key 不存在时,新增 dict["atk"] = 25; // key 已存在时,修改 ``` 区别: 1. `Add` 遇到重复 key 会报错 2. `dict[key] = value` 遇到重复 key 会覆盖旧值 ---- # 增删查改 增加: ```csharp dict.Add("def", 10); ``` 删除: ```csharp dict.Remove("def"); dict.Clear(); ``` 查找键: ```csharp bool hasHp = dict.ContainsKey("hp"); ``` 查找值: ```csharp bool hasValue = dict.ContainsValue(100); ``` 修改: ```csharp dict["hp"] = 120; ``` 取值: ```csharp int hp = dict["hp"]; ``` ---- # TryGetValue 很常用 直接取值: ```csharp int hp = dict["hp"]; ``` 问题: 如果 key 不存在 会报错 更稳的写法: ```csharp if (dict.TryGetValue("hp", out int hp)) { Console.WriteLine(hp); } else { Console.WriteLine("没有这个键"); } ``` 说明: 1. `TryGetValue` 会返回 `true` 或 `false` 2. 如果找到 key,就把对应值放进 `out` 变量 3. 如果项目里经常“先查再取”,`TryGetValue` 很实用 ---- # 遍历 遍历键值对: ```csharp Dictionary dict = new Dictionary(); dict.Add("语文", 90); dict.Add("数学", 95); foreach (KeyValuePair item in dict) { Console.WriteLine(item.Key + " : " + item.Value); } ``` 只遍历键: ```csharp foreach (string key in dict.Keys) { Console.WriteLine(key); } ``` 只遍历值: ```csharp foreach (int value in dict.Values) { Console.WriteLine(value); } ``` 注意: 复习时不要把 `Dictionary` 当成“按下标顺序排列的列表” 它的核心用途是通过 key 查 value ---- # key 不能重复 错误写法: ```csharp Dictionary dict = new Dictionary(); dict.Add("hp", 100); dict.Add("hp", 200); ``` 原因: `Dictionary` 中的 key 必须唯一 重复添加同一个 key 会报错 如果想修改旧值: ```csharp dict["hp"] = 200; ``` ---- # key 一般不能为 null 错误写法: ```csharp Dictionary dict = new Dictionary(); // dict.Add(null, 100); ``` 原因: `Dictionary` 的 key 不能为 `null` 补充: 如果 `TValue` 是引用类型或可空类型 value 可以是 `null` 示例: ```csharp Dictionary dict = new Dictionary(); dict["name"] = null; ``` ---- # 和 Hashtable 的区别 `Hashtable`: 非泛型 key 和 value 都按 `object` 处理 取值时常常需要强制类型转换 `Dictionary`: 泛型 key 和 value 类型明确 编译期就能检查类型错误 使用起来更安全,更常见 对比表: | 对比点 | `Hashtable` | `Dictionary` | |---|---|---| | 类型 | 非泛型 | 泛型 | | 键和值 | `object` | 指定类型 | | 类型安全 | 较弱 | 更强 | | 取值 | 常要强转 | 一般不用强转 | | 推荐程度 | 主要用于学习旧集合 | 实际开发常用 | ---- # 和 List 的区别 | 对比点 | `List` | `Dictionary` | |---|---|---| | 存储方式 | 单个元素 | 键值对 | | 查找方式 | 常用下标 | 常用 key | | key | 没有 | 必须唯一 | | 适合场景 | 一组同类型数据 | 根据唯一键查数据 | 一句话: `List` 更像“列表” `Dictionary` 更像“字典” ---- # 基础案例:角色表 ```csharp using System; using System.Collections.Generic; class Player { public string Name; public int Level; public Player(string name, int level) { Name = name; Level = level; } } class Program { static void Main(string[] args) { Dictionary players = new Dictionary(); players.Add(1001, new Player("小明", 10)); players.Add(1002, new Player("小红", 12)); players.Add(1003, new Player("小刚", 8)); if (players.TryGetValue(1002, out Player player)) { Console.WriteLine(player.Name + " " + player.Level); } } } ``` 输出: ```text 小红 12 ``` 理解: 1. `1001`、`1002`、`1003` 是玩家编号 2. 通过编号可以快速找到对应玩家对象 3. 这种“编号 -> 对象”的场景非常适合用 `Dictionary` ---- # 常用成员 ```csharp Dictionary dict = new Dictionary(); dict.Add("A", 1); dict["B"] = 2; Console.WriteLine(dict.Count); Console.WriteLine(dict.ContainsKey("A")); Console.WriteLine(dict.ContainsValue(2)); dict.Remove("A"); dict.Clear(); ``` 常用方法 / 成员: 1. `Add(TKey key, TValue value)`:添加键值对 2. `Remove(TKey key)`:删除指定 key 3. `Clear()`:清空 4. `ContainsKey(TKey key)`:判断 key 是否存在 5. `ContainsValue(TValue value)`:判断 value 是否存在 6. `TryGetValue(TKey key, out TValue value)`:安全取值 7. `Keys`:获取所有键 8. `Values`:获取所有值 9. `Count`:键值对数量 10. `dict[key]`:通过 key 取值或赋值 ---- # 注意 1. `Dictionary` 在 `System.Collections.Generic` 命名空间中 2. 它是泛型键值对集合 3. key 必须唯一 4. `Add` 遇到重复 key 会报错 5. `dict[key] = value` 可以新增,也可以覆盖旧值 6. 用不存在的 key 直接取值可能报错 7. 更稳的取值方式通常是 `TryGetValue` 8. 它最核心的优势是“通过 key 快速找 value” ---- # 易错点 1. 不要把 `Dictionary` 当数组或 `List` 来用 2. 不要默认 key 一定存在 3. `ContainsKey` 判断的是键,不是值 4. `ContainsValue` 可以用,但实际开发里更常关心 key 5. 重复 `Add` 同一个 key 会报错 错误示例: ```csharp Dictionary dict = new Dictionary(); dict.Add("hp", 100); // Console.WriteLine(dict["mp"]); ``` 原因: `"mp"` 这个 key 不存在 直接取值可能报错 ---- # 一句话记忆 ==Dictionary 是通过唯一 key 快速查找 value 的泛型键值对集合。== 再压缩一点: ==List 用下标找,Dictionary 用 key 找。== ---- # 面试/复习时怎么说 可以这样答: “`Dictionary` 是 C# 中非常常用的泛型键值对集合,适合通过唯一 key 快速查找 value。 它的 key 不能重复,常用操作有 `Add`、`Remove`、`ContainsKey` 和 `TryGetValue`。 相比 `Hashtable`,`Dictionary` 类型更安全,不需要频繁强制类型转换,所以实际开发中更常用。” ---- 引用: 1. Microsoft Learn: [Dictionary Class](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-9.0) 2. Microsoft Learn: [Dictionary.TryGetValue Method](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.trygetvalue?view=net-9.0) 3. Microsoft Learn: [System.Collections.Generic Namespace](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic?view=net-9.0) #Dictionary #字典 #泛型集合 #集合 #进阶