Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object.Equals: everything is equal by default

While reading Jeffrey Richter's CLR via C# 4th edition (Microsoft Press), the author at one point states that while Object.Equals currently checks for identity equality, Microsoft should have implemented the method like this:

public class Object {
    public virtual Boolean Equals(Object obj) {
        // The given object to compare to can't be null
        if (obj == null) return false;

        // If objects are different types, they can't be equal.
        if (this.GetType() != obj.GetType()) return false;

        // If objects are same type, return true if all of their fields match
        // Because System.Object defines no fields, the fields match
        return true;
    }
}

This strikes me as very odd: every non-null object of the same type would be equal by default? So unless overridden: all instances of a type are equal (e.g. all your locking objects are equal), and return the same hash code. And assuming that the == on Object still checks reference equality, this would mean that (a == b) != a.Equals(b) which would also be strange.

I think the idea of things being equal if it is the exact same thing (identity) is a better idea than just making everything equal unless overridden. But this is a well known book's 4th edition published by Microsoft, so there must be some merit to this idea. I read the rest of the text but could not help but wonder: Why would the author suggest this? What am I missing here? What is the great advantage of Richter's implementation over the current Object.Equals implementation?

like image 982
Daniel A.A. Pelsmaeker Avatar asked Feb 06 '13 02:02

Daniel A.A. Pelsmaeker


People also ask

Can you use equals () with objects?

The equals() method is a static method of the Objects class that accepts two objects and checks if the objects are equal. If both the objects point to null , then equals() returns true .

What is the default behavior of equal method of class object?

The equals() method compares the equality of two objects. The Object class defines the default implementation for this method.. By default, the equals() method returns false if the two objects aren't the same instance... This may seem obvious but sometimes the default behavior is not what you want...

Can objects be equal?

It is also possible that an object is equal to another given object, then the equals() method follow the equivalence relation to compare the objects. Reflexive: If x is a non-null reference, the calling of x. equals(x) must return true.

What is default behavior of equals method in Java?

The equals method checks by default whether the object given as a parameter has the same reference as the object it is being compared to. In other words, the default behaviour checks whether the two objects are the same. If the reference is the same, the method returns true , and false otherwise.


1 Answers

The current default Equals() does what is known as a shallow compare (or reference compare), and then doesn't check any further if the references differ.

I think this is perfectly acceptable for a base implementation. I certainly wouldn't think that it is wrong or incomplete.

Richter's example1 which you quote is also perfectly legitimate for the base System.Object. The issue with his implementation is that it arguably should be declared abstract2 - with his method you will end up with an unreliable Equals() on derived objects if you do not override it (because Equals() is supposed to do a deep compare). Having to override this method on all derived objects would be a lot of work, therefore the Microsoft way is better as a default. So in essense you are correct: Richter's example is odd - it is better to default to not equal rather then the other way round (defaulting to true would lead to some rather interesting behavior if people forgot to override it).

(Just for easy reference, here is the default implementation as published in the book)

enter image description here



1: Richter is a smart man who knows his stuff and I wouldn't generally argue with anything he says. You have to understand that the MS engineers would have had to think long and hard about a lot of things, knowing that they didn't have the flexibility of being able to get it wrong and then just fix stuff later. No matter how right they are, people will always second guess them at a later date, and offer alternative opinions. That doesn't mean the original is wrong or the alternative is wrong - it simply means there was an alternative.

2: Which of course means that there would be no base implementation, which is good because it would have been unreliable.

like image 179
slugster Avatar answered Sep 21 '22 05:09

slugster