Click here to Skip to main content
Click here to Skip to main content

Talk about System.Object Equals and GetHashcode

By , 14 Mar 2013
 

Introduction

Just a simple example to show why we need to override GetHashCode if we override Equals, just understanding why "if two objects are equal, they would better have the same HashCode".

Background

In C#, when we create a class, it is automatically inherited from System.Object, and we inherit the Equals and GetHashCode methods.  We can override them, but if we override Equals without overriding GetHashCode, we will get a warning message: "overrides Object.Equals(object o) but does not override Object.GetHashCode()".

Why is Microsoft warning you this? If you don't plan to use your object as a key for hash collections (like Hashtable, Dictionary, etc.), it is OK. Otherwise you will face a problem.

Using the Code

I define a class and override the Equals method. If the Ids are the same, the two objects are equal. In the RunOverEqualsWithoutHashCode method, I create a Hashtable using HashCodeWalkthrough as key and store 100 items, then I tried to find the A50, but got nothing.

Then if I override the GetHashCode method, I can find the items in the Hashtable.

class HashCodeWalkthrough
{
    //public override int GetHashCode()
    //{
    //    return Convert.ToInt32(id.Substring(1));
    //}

    /// <summary>
    /// If Id is the same,then Equals
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public override bool Equals(object obj)
    {
        if (null == obj) return false;
        HashCodeWalkthrough obj2 = obj as HashCodeWalkthrough;
        if (obj2 == null) return false;
        return this.id.Equals(obj2.Id);
    }

    #region Properties
    string name = string.Empty;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    string id = string.Empty;

    public string Id
    {
        get { return id; }
        set { id = value; }
    }
    #endregion
}

private static void RunOverEqualsWithoutHashCode()
{
    //create a 100 items hashtable with HashCodeWalkthrough obj as the key
    Hashtable hash = new Hashtable();
    for (int i = 0; i < 99; i++)
    {
        hash.Add(new HashCodeWalkthrough() { Id = "A" + i, Name = "Name" + i },
            "Value" + i);
    }

    HashCodeWalkthrough search50 = new HashCodeWalkthrough() { Id = "A50", Name = "Name50" };
    Console.WriteLine(hash.ContainsKey(search50));
    Console.WriteLine("Find the 50th in Hashtable");
    string value = hash[search50] as string;
    Console.WriteLine(value);
    
}

public override int GetHashCode()
{
    return Convert.ToInt32(id.Substring(1));
}

Points of Interest

The trick is that when storing data in a hash collection, it uses the object's Hashcode to find a bucket. When getting items, it also uses the key object's Hashcode to search the bucket. Although the two key objects Equals (because we override), they have different Hashcodes (by default System.Object returns a unique ID in the AppDomain for any new object), so when getting, it will find no bucket, so that item will actually be missing.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

李建兴
Web Developer
China China
Member
Right now I am a college student.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberKarsten Gutjahr19 Mar '13 - 1:55 
SuggestionGood hintsmemberbensonxiong18 Mar '13 - 16:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 14 Mar 2013
Article Copyright 2012 by 李建兴
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid