Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Equals() but not checking all fields - what will happen?

Tags:

c#

.net

If I override Equals and GetHashCode, how do I decide which fields to compare? And what will happen if I have two objects with two fields each, but Equals only checks one field?

In other words, let's say I have this class:

class EqualsTestClass
{
    public string MyDescription { get; set; }
    public int MyId { get; set; }

    public override bool Equals(object obj)
    {
        EqualsTestClass eq = obj as EqualsTestClass;
        if(eq == null) {
            return false;
        } else {
            return MyId.Equals(eq.MyId);
        }
    }

    public override int GetHashCode()
    {
        int hashcode = 23;
        return (hashcode * 17) + MyId.GetHashCode();
    }
}

I consider two objects Equal if they have the same MyId. So if the Id is equal but the description is different, they are still considered equal.

I just wonder what the pitfalls of this approach are? Of course, a construct like this will behave as expected:

        List<EqualsTestClass> test = new List<EqualsTestClass>();

        EqualsTestClass eq1 = new EqualsTestClass();
        eq1.MyId = 1;
        eq1.MyDescription = "Des1";

        EqualsTestClass eq2 = new EqualsTestClass();
        eq2.MyId = 1;
        eq2.MyDescription = "Des2";

        test.Add(eq1);
        if (!test.Contains(eq2))
        {
            // Will not be executed, as test.Contains is true
            test.Add(eq2);
        }

As eq2 is value-equal to eq1, it will not be added. But that is code that I control, but I wonder if there is code in the framework that could cause unexpected problems?

So, should I always add all public Fields in my Equals() Comparison, or what are the guidelines to avoid a nasty surprise because of some bad Framework-Mojo that was completely unexpected?

like image 637
Michael Stum Avatar asked Mar 04 '09 01:03

Michael Stum


People also ask

What happens if we don't override equals method?

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object. hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

What is the reason for overriding equals () method?

We can override the equals method in our class to check whether two objects have same data or not.

What happens if we do not override hashCode () and equals () in HashMap?

If you don't override hashcode() then the default implementation in Object class will be used by collections. This implementation gives different values for different objects, even if they are equal according to the equals() method.

Can we override equals method?

You can override the equals method on a record, if you want a behavior other than the default. But if you do override equals , be sure to override hashCode for consistent logic, as you would for a conventional Java class.


2 Answers

The reason for overriding Equals() is that you define, what it means for two instances to be equal. In some cases that means that all fields must be equal, but it doesn't have to. You decide.

For more information see the documentation and this post.

like image 93
Brian Rasmussen Avatar answered Oct 30 '22 17:10

Brian Rasmussen


I don't think you need to worry about the Framework in this instance. If you as the Class Designer consider two instances of that class to be equal if they share the same MyId, then, you only need to test MyId in your overriden Equals() and GetHashCode() methods.

like image 44
Scott Ferguson Avatar answered Oct 30 '22 18:10

Scott Ferguson