这是在C#中。我有一个问题,即Dictionary.ContainsKey返回false,即使我知道要在那里的密钥。
不幸的是,我没有任何代码可以显示。代码不容易汇总;它分布在多个类中,并通过事件等触发。我写的快速单元测试没有重现问题。
以下是调试会话期间即时窗口的输出(添加注释并更改以保护详细信息):
// throws KeyNotFoundException
myDict[key]
// throws KeyNotFoundException
myDict[new MyKey("SomeString .1", "SomeOtherString", SomeEnum.Foo)]
// Element [5] is the key
myDict.Keys
Count = 10
[0]: {...}
[1]: {...}
[2]: {...}
[3]: {...}
[4]: {...}
[5]: {Foo SomeOtherString SomeString .1}
[6]: {...}
[7]: {...}
[8]: {...}
[9]: {...}
// Get key at element [5]
enumerator.Current
{Foo SomeOtherString SomeString .1}
[My.Namespace.KeyType]: {Foo SomeOtherString SomeString .1}
SomeEnum: Foo
SomeOtherStringProperty: "SomeOtherString"
// key used to do lookup
key
{Foo SomeOtherString SomeString .1}
[My.Namespace.KeyType]: {Foo SomeOtherString SomeString .1}
SomeEnum: Foo
SomeOtherStringProperty: "SomeOtherString"
// hash codes of key in dictionary matches hash code of lookup key
enumerator.Current.GetHashCode()
193014103
key.GetHashCode()
193014103
一些额外的说明:
有谁知道为什么会这样?
感谢您提供任何帮助 - 我在这里没有想法。
答案 0 :(得分:4)
用作键的类型具有GetHashCode和Equals的重写方法。
这是我要检查的第一件事。如果哈希码基于可变值,则肯定会导致此问题。
来自MSDN:
通常,对于可变引用类型,只应在以下情况下覆盖GetHashCode:
您可以从不可变的字段计算哈希码;或
当对象包含在依赖于其哈希码的集合中时,您可以确保可变对象的哈希码不会更改。
否则,您可能会认为哈希表中的可变对象丢失了。如果您确实选择覆盖GetHashCode以获取可变引用类型,那么您的文档应该清楚地表明,当对象存储在哈希表中时,您的类型的用户不应修改对象值。