Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Equals and type casting

In this following example the third evaluation returns false, all good, but the fourth example returns true..
I don't quite understand how this works however, by default Object.Equals compares two references for object equality, and seeing as a and b both point to a unique instance of a string, this should return false, which it does in the third example but not in the fourth.
Now I understand why it returns true in the 2nd example seeing as the .Equals() method is overridden in the string class, but in the fourth example we're casting this string as an object.
So wouldn't it call Object.Equals in this case?

static void Main()
{
    // Create two equal but distinct strings
    string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
    string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});

    Console.WriteLine (a == b); // Returns true
    Console.WriteLine (a.Equals(b)); // Returns true

    // Now let's see what happens with the same tests but
    // with variables of type object
    object c = a;
    object d = b;

    Console.WriteLine (c == d); // Returns false
    Console.WriteLine (c.Equals(d)); // Returns true
}
like image 344
Overly Excessive Avatar asked Apr 23 '14 06:04

Overly Excessive


People also ask

Can you override equals method?

All classes in Java inherit from the Object class, directly or indirectly (See point 1 of this). The Object class has some basic methods like clone(), toString(), equals(),.. etc. We can override the equals method in our class to check whether two objects have same data or not.

What are equals () and hashCode () overriding rules?

"If two objects are equal using Object class equals method, then the hashcode method should give the same value for these two objects." So, if in our class we override equals() we should override hashcode() method also to follow this rule.

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.

When should we override hashCode and equals?

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.


1 Answers

The clue is the words "by default". string overrides object.Equals with a custom implementation. Since object.Equals is a polymorphic method (virtual / override / etc), the most-derived implementation gets used even if the variable (/expression) type is object.

==, however, is not polymorphic; the implementation used depends entirely on the variable (/expression) type. In this case, since the known type is object, the only comparison available is reference equality.

Perhaps more succinctly:

class Foo {
    public override string ToString() { return "hi"; }
}
//...
object obj = new Foo();
string s = obj.ToString(); // this is "hi"

This is the same principle: the most derived overload of a virtual method is used, regardless of the type that the compiler knows about (object in this case).

like image 119
Marc Gravell Avatar answered Oct 18 '22 23:10

Marc Gravell