什么原因会导致dictionary.ContainsKey(dictionary.Keys.First())返回false?

3

dictionary.Keys.First().GetHashCode() == dictionary.Keys.First().GetHashCode() 返回 true,dictionary.Keys.First() == dictionary.Keys.First() 返回 true。

有什么缺失吗?为什么字典无法找到此对象?

字典类型为:Dictionary<ExceptionWrapper<Exception>, List<int>>

以下是 ExceptionWrapper.EqualsExceptionWrapper.GetHashCode 的实现:

public override int GetHashCode() {
  return (typeof(TException).FullName + exception.Message + exception.StackTrace).GetHashCode();
}

public override bool Equals(object obj) {
  return 
    obj is ExceptionWrapper<TException>
&& (obj as ExceptionWrapper<TException>).GetHashCode() == GetHashCode();
}

2
dictionary的类型是什么?一个代码片段可能会有所帮助。 - dlev
字典是否被不同的线程访问?键类型是什么?它是否与“GetHashCode”的定义不一致地覆盖了“Equals”? - Lee
没有多线程正在进行。 - MushinNoShin
1
从一个连接的 “字符串” 创建哈希并不是一个好的风格。你的 Equals 方法也非常错误;它会在两个哈希值巧合相等时返回 true。这些只是评论,而不是对你问题的回答。 - Jeppe Stig Nielsen
感谢您对equals的反馈。是的,这确实不够严谨。我以前可能会说自己匆忙,但这并不是一个真正的借口。 - MushinNoShin
1个回答

4

该键在其具有一个哈希码时首次添加到Dictionary<,>中。之后,该对象被“改变”以使哈希码成为某个新数字。

因此,Dictionary<,>处于无效状态。

请勿更改可能是哈希表中某个键的对象的哈希码,以改变该对象的方式进行“mutate”。


我认为没有任何变异发生。我将尝试将哈希码存储在内存中,以确保它解决了问题。谢谢你的建议。 - MushinNoShin
如果是因为状态变化,为什么 dictionary.containsKey(dictionary.Keys.First()) 不返回 true? - MushinNoShin
这似乎是最有可能的嫌疑人... ContainsKey仅检查对象的哈希码桶...因此,如果哈希码更改,则现在正在错误的桶中查找对象。 - Kevin
1
@MushinNoShin 因为哈希码改变时,Dictionary<,> 完全损坏。关键字被丢失。搜索关键字只在一个“桶”中进行,即对应于新哈希的那个桶,但是由于该项位于另一个桶中,因此找不到任何内容。 - Jeppe Stig Nielsen
就这样,谢谢。现在我要试图弄清楚那个异常是如何变化的。 - MushinNoShin
1
如果在catch块中处理的异常稍后使用throw语句重新抛出,则该重新抛出将修改异常的堆栈跟踪。 - Jeppe Stig Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接