Dictionary初始化须用new Dictionary()后调用Add()或索引器赋值;Add()禁止重复键,索引器自动插入或覆盖;推荐集合初始化、TryGetValue()安全取值、自定义键重写GetHashCode/Equals,避免null键与可变哈希字段。

Dictionary 初始化和添加值的正确写法
直接用 new Dictionary 创建实例后,必须用 Add() 或索引器赋值才能存入键值对。用错方式会导致运行时异常或静默覆盖。
-
Add(key, value)要求key不能已存在,否则抛出ArgumentException - 用索引器
dict[key] = value会自动插入新项,或覆盖已有键的值 —— 这是多数场景真正需要的操作 - 初始化时可用集合初始值设定项:
var dict = new Dictionary
{ { "a", 1 }, { "b", 2 } };
安全获取值:不要直接用 dict[key] 访问未知键
对不存在的键使用 dict[key] 会触发 KeyNotFoundException(除非值类型有默认值且字典被允许隐式创建,但这是危险行为)。
- 优先用
TryGetValue(key, out value)—— 返回bool表示是否存在,同时输出值,无异常、无装箱、性能最优 - 若只需判断存在性,用
ContainsKey(key),但后续再取值需二次查找,不推荐连用 -
GetValueOrDefault(key)可返回默认值(如0或null),但无法区分“键不存在”和“键存在但值为默认值”两种情况
键类型必须满足相等性和哈希一致性
自定义类作键时,GetHashCode() 和 Equals() 必须同步重写,否则 Add() 和 TryGetValue() 行为不可预测。
- 字符串、数字、枚举等内置类型可直接用,无需额外处理
- 若用
record,编译器自动生成合理实现,适合轻量键类型 - 避免用可变字段参与
GetHashCode()计算 —— 键插入字典后修改该字段,会导致再也找不到这个键
常见错误:null 键和引用类型值的陷阱
Dictionary 允许 null 作为键(当 TKey 是引用类型),但容易引发空引用异常,尤其在未检查就调用 TryGetValue() 后直接使用 out 变量时。
- 若
TKey是引用类型(如string),null是合法键,dict[null] = 42;有效 - 若
TValue是引用类型,TryGetValue()成功时out参数才被赋值;失败时该变量保持原值 —— 别假设它为null - 泛型约束
where TKey : notnull可在编译期禁止null键,推荐在明确不需要 null 键时加上
TryGetValue() 的 out 变量生命周期 —— 这两个点一旦出错,问题往往延迟暴露,调试成本远高于初始化时多写一行约束或检查。










