C# – Equals() and GetHashCode()

GetHashCode and Equals methods are used to compare objects i.e. when they are inserted into dictionary.
At first GetHashCode is invoked. When object hash code is not colliding – objects are treated as different. If hash codes are the same then Equals method is invoked.
General rule for GetHashCode method impementation: it should always return the same value in the whole object’s lifetime. It means properties used to calculate it should be immutable.
General rule for Equals method implementation: it should check for null and type of compared object.
You always should to implement GetHashCode method when you are overriding Equals method and vice versa.
What’s more when two objects have the same hashcodes, it doesn’t mean that they are identical. But when two objects are identical, they have the same hashcode.

    [TestClass]
    public class EqualsAndGetHashcodeTests
    {

        [TestMethod]
        public void TestComparing()
        {
            var p1 = new Person(1, "John", 1950);
            var p2 = new Person(2, "John", 1960);
            var p3 = new Person(1, "John", 1970);
            var p4 = new Person(1, "John", 1950);

            var people = new HashSet<Person>(); //hash set collects unique elements
            people.Add(p1); //p1 will be added as it is first unique item
            people.Add(p2); //p2 will be added as it has different hash code (equals method won't be called)
            people.Add(p3); //p3 will be added, hashcode is the same as for p1, but Equals method is called and will return false
            people.Add(p4); //p4 won't be added, as hashcode is the same as p1 and Equals method will return true
        }

        private class Person
        {
            public Person(int id, string name, int birthYear)
            {
                Id = id;
                Name = name;
                BirthYear = birthYear;
            }

            public int Id { get; private set; }
            public string Name { get; set; }
            public int BirthYear { get; set; }

            public override bool Equals(object obj)
            {
                if (obj == null)
                    return false;

                if (GetType() != obj.GetType())
                    return false;

                var theOtherPerson = obj as Person;

                return Name == theOtherPerson.Name && BirthYear == theOtherPerson.BirthYear;
            }

            public override int GetHashCode()
            {
                return Id;
            }
        }
    }

Notice that you can easily implement GetHashCode method for anonymous types like this:

            public override int GetHashCode()
            {
                return new { Id, BirthYear }.GetHashCode();
            }

For more about Equals method see: C# – Equals()

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s