1

I have a Dictionary and every time I call the ContainsKey method it returns false. Take the following example

 Boolean found = dict.ContainsKey(new Group("group1", "test"));

The found variable is false eventhough the visual studio debugger shows that a Group with the name "group1" and type "test" is present in dict. What is going on?

My Group class has two String fields (type and name) and I override the Equals method

public override bool Equals(object obj)
{
    Group otherGroup = (Group)obj;
    return this.name == otherGroup.name && this.type == otherGroup.type;
}
Ben
  • 643
  • 2
  • 11
  • 25
  • 1
    And GetHashCode is overriden too? – Tomas Voracek Sep 19 '11 at 19:41
  • 1
    It looks like you've been burned by [not overriding GetHashCode](http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c#371348). – Adam Maras Sep 19 '11 at 19:42
  • 1
    See: http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c – Marc Gravell Sep 19 '11 at 19:42
  • If you override `Equals` you should always also override `GetHashCode` so that it returns a unique value for your `Group` objects. Also, duplicate of: http://stackoverflow.com/questions/6129497/c-dictionary-containskey – Cᴏʀʏ Sep 19 '11 at 19:43
  • @CoryLarson Thanks for the question reference; I didn't find that one in my search – Ben Sep 19 '11 at 20:15

3 Answers3

4

You should override GetHashCode method

An example of HashMethod for a class containing 2 string properties

public override int GetHashCode()
{
    unchecked
    {
        return ((name != null ? name.GetHashCode() : 0)*397) ^ (type != null ? type.GetHashCode() : 0);
    }
}
meziantou
  • 20,589
  • 7
  • 64
  • 83
  • I'm new to C# what does the unchecked keyword do? Also, why are you only multiplying the name hash code by 397? – Ben Sep 19 '11 at 20:16
  • The unchecked keyword is used to suppress overflow-checking for integral-type arithmetic operations and conversions. – meziantou Sep 19 '11 at 20:18
  • 397 is a prime number. http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/ – meziantou Sep 19 '11 at 20:20
  • I got why you choose to use 397 but I'm confused as to why you only multiplied the name hash code by 397 and not the type hash code as well? – Ben Sep 19 '11 at 20:25
  • This hash method is generated by Resharper. I think you should ask them directly ;) – meziantou Sep 19 '11 at 20:29
4

You need to override GetHashCode():

http://msdn.microsoft.com/en-us/library/ms182358(v=vs.80).aspx

GetHashCode returns a value based on the current instance that is suited for hashing algorithms and data structures such as a hash table. Two objects that are the same type and are equal must return the same hash code to ensure that instances of System.Collections.HashTable and System.Collections.Generic.Dictionary work correctly.

Samich
  • 29,157
  • 6
  • 68
  • 77
0

I know this question already have an accepted answer but i'll share my dirty solution too.

Boolean found = 
   dict.Keys.Any(key => 
                 key.Equals("key", StringComparison.InvariantCultureIgnoreCase));
Ahmet Kakıcı
  • 6,294
  • 4
  • 37
  • 49