Dictionary.GetKey returns false even if key is present - GetHashCode / Equals has already been rewritten

It's in C #. I have a problem where Dictionary.ContainsKey returns false even though I know the key is there.

I don't have any code to show, unfortunately. The code is not easy to put together; it spreads across several classes and is triggered via events and so on. A quick unit test I wrote did not reproduce the problem.

Here is the output of the immediate window during a debug session (comments added and changed to protect details):

// 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

      

Some additional notes:

  • The type used as a key has overridden methods for GetHashCode and Equal.
  • The dictionary is built like a new dictionary () with no additional constructor arguments.
  • Debugging, I have verified that GetHashCode is Called on key type but not Equals (obj)
  • When only one loaded DLL is executed that has a key type, so it is probably not of the same type in different versions of the same DLL

Does anyone know why this might be happening?

Thanks for any help - I'm running out of ideas.

+3


source to share


1 answer


The type used as a key has overridden methods for GetHashCode and Equals.

This is the first thing I checked. If the hashcode is based on a mutable value, it can definitely cause this problem.



From MSDN :

In general, for mutable link types, you should only override GetHashCode if:

  • You can compute the hash code from fields that don't change; or

  • You can ensure that the hash code of the mutable object does not change as long as the object is contained in a collection that relies on its hash code.

Otherwise, you might think that the changed object is lost in the hash table. If you choose to override GetHashCode for a mutable reference type, it should be clear in your documentation that users of your type should not change the values ​​of objects while the object is stored in a hash table.

+4


source







All Articles