尽管 Comparer.Equals 返回 true,但字典不包含键
Dictionary does not contain key despite Comparer.Equals returning true
我一直在寻找一个错误,我有一个字典坚持说一个键不存在,尽管它的比较器实际上说它存在。例如,在下面的片段中,抛出异常:
if (!dictionary.ContainsKey(key))
{
var comparer = dictionary.Comparer;
foreach (var _key in dictionary.Keys)
{
if (comparer.Equals(key, _key) &&
comparer.Equals(_key, key) &&
comparer.GetHashCode(key) == comparer.GetHashCode(_key) &&
comparer.GetHashCode(_key) == comparer.GetHashCode(key))
{
throw new Exception("Key exists, but dictionary doesn't find it");
}
}
}
字典是通用的 Dictionary<TKey, TValue>
,带有默认的相等比较器(空构造函数)。 TKey
class 实现了正确的 GetHashCode
和 Equals
方法。
这里有什么我可能遗漏的吗?我完全不知所措!
唯一可能发生这种情况的情况是键是可变的,并且在将其插入字典后其内容已更改。
事情是这样发生的:
- 你在字典中插入了一个键;字典获取其哈希码,并将其放入相应的哈希桶中,通过调用
Equals
解决冲突
- 你改变了密钥;现在它的哈希码不再对应于它的哈希桶
- 你打电话给
ContainsKey
。字典在其新存储桶中查找键。由于密钥不存在,因此报告false
- 当您迭代字典时,将返回所有键,包括不再位于其合法存储桶中的键。这就是为什么您会在
foreach
循环中受到打击。
我一直在寻找一个错误,我有一个字典坚持说一个键不存在,尽管它的比较器实际上说它存在。例如,在下面的片段中,抛出异常:
if (!dictionary.ContainsKey(key))
{
var comparer = dictionary.Comparer;
foreach (var _key in dictionary.Keys)
{
if (comparer.Equals(key, _key) &&
comparer.Equals(_key, key) &&
comparer.GetHashCode(key) == comparer.GetHashCode(_key) &&
comparer.GetHashCode(_key) == comparer.GetHashCode(key))
{
throw new Exception("Key exists, but dictionary doesn't find it");
}
}
}
字典是通用的 Dictionary<TKey, TValue>
,带有默认的相等比较器(空构造函数)。 TKey
class 实现了正确的 GetHashCode
和 Equals
方法。
这里有什么我可能遗漏的吗?我完全不知所措!
唯一可能发生这种情况的情况是键是可变的,并且在将其插入字典后其内容已更改。
事情是这样发生的:
- 你在字典中插入了一个键;字典获取其哈希码,并将其放入相应的哈希桶中,通过调用
Equals
解决冲突
- 你改变了密钥;现在它的哈希码不再对应于它的哈希桶
- 你打电话给
ContainsKey
。字典在其新存储桶中查找键。由于密钥不存在,因此报告false
- 当您迭代字典时,将返回所有键,包括不再位于其合法存储桶中的键。这就是为什么您会在
foreach
循环中受到打击。