尽管Comparer.Equals返回true,但Dictionary不包含键

时间:2018-01-30 17:34:00

标签: c# .net dictionary equality

我一直在寻找一个错误,我有一本字典,坚持说一把钥匙不存在,尽管它的比较实际上说它确实存在。例如,在以下代码段中,抛出了异常:

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类实现了正确的GetHashCodeEquals方法。

这里有什么我可能会遗失的吗?我完全失败了!

1 个答案:

答案 0 :(得分:7)

唯一可能发生的方法是,如果密钥是可变的,并且在将内容插入字典后,其内容已经更改。

以下是它的发生方式:

  • 您将密钥插入字典;字典获取其哈希码,并将其放入相应的哈希桶中,通过调用Equals解决冲突
  • 你改变了关键;现在它的哈希码不再对应于它的哈希桶
  • 您致电ContainsKey。字典在其新存储桶中查找密钥。由于密钥不存在,因此报告了false
  • 当您迭代字典时,将返回所有键,包括那些不再在其合法存储桶中的键。这就是为什么你在foreach循环中受到欢迎的原因。