C#中装箱类型相等性判断与Dictionary键比较规则疑问
装箱值类型作为Dictionary键的相等判断规则解释
现象背后的核心原因
1. object类型的==运算符逻辑
==是静态运算符重载,执行逻辑由编译时类型决定:
- 当比较的两个变量编译时类型为
object时,默认执行引用相等性比较 - 你代码中
boxedI和boxedN是两次独立装箱生成的不同堆对象,引用地址不同,所以boxedI == boxedN返回false
你可以新增一行验证代码确认逻辑:
Console.WriteLine(boxedI.Equals(boxedN)); // 输出为true
2. Dictionary的键相等判断逻辑
Dictionary判断键是否相等依赖构造时传入的IEqualityComparer<T>,未显式指定时使用默认的EqualityComparer<object>.Default,它的判断逻辑分为两步:
- 第一步:调用键的
GetHashCode()方法,判断哈希值是否相等,哈希值不等则直接判定为键不相等 - 第二步:如果哈希值相等,再调用键的
Equals(object obj)方法,返回true才判定为键相等
对于装箱的int类型:
GetHashCode()重写为基于值计算,两个值为5的装箱int返回的哈希值完全一致Equals(object obj)也重写为基于值比较,所以boxedI.Equals(boxedN)返回true- 因此Dictionary会判定两个装箱对象为同一个键,所以
ContainsKey(boxedN)返回true,新增时抛出重复键异常
存在的认知偏差点
- 错误认为
==运算符和Dictionary的相等判断逻辑一致:Dictionary的判断依据是GetHashCode()+Equals组合,和==运算符没有关系 - 错误认为
GetHashCode是相等判断的唯一依据:哈希值相等只是相等的必要非充分条件,最终判断要依赖Equals方法的返回值
内容的提问来源于stack exchange,提问作者Skary
相关产品推荐
相关产品推荐

