Dictionary.GetKey返回False,即使Key存在 - GetHashCode / Equals已被覆盖

时间:2014-09-10 00:39:50

标签: c# dictionary keynotfoundexception

这是在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

一些额外的说明:

  • 用作键的类型具有GetHashCode和的重写方法 等于。
  • 字典构造为新的Dictionary() 没有额外的构造函数参数。
  • 通过调试,我已经验证了这一点 调用密钥类型中的GetHashCode,但不调用Equals(obj)
  • 当 应用程序运行时,只加载了一个具有密钥类型的DLL, 所以它可能不是不同版本中相同类型的情况 相同的DLL

有谁知道为什么会这样?

感谢您提供任何帮助 - 我在这里没有想法。

1 个答案:

答案 0 :(得分:4)

  

用作键的类型具有GetHashCode和Equals的重写方法。

这是我要检查的第一件事。如果哈希码基于可变值,则肯定会导致此问题。

来自MSDN

  

通常,对于可变引用类型,只应在以下情况下覆盖GetHashCode:

     
      
  • 您可以从不可变的字段计算哈希码;或

  •   
  • 当对象包含在依赖于其哈希码的集合中时,您可以确保可变对象的哈希码不会更改。

  •   
     

否则,您可能会认为哈希表中的可变对象丢失了。如果您确实选择覆盖GetHashCode以获取可变引用类型,那么您的文档应该清楚地表明,当对象存储在哈希表中时,您的类型的用户不应修改对象值。