Home > View Post

The difference between Equals equals

This has been written about many times and most people are aware that '==' and .Equals() aren't always one and the same. Let's recap on the difference.

bool b1 = true;
bool b2 = true;

object o1 = (object) true;
object o2 = (object) true;

Assert.IsTrue(b1 == b2) // :)
Assert.IsTrue(o1 == o2) // Fails!!!

Assert.IsTrue(b1.Equals(b2)); // :)
Assert.IsTrue(o1.Equals(o2)); // :D

The reason the second assert fails is because operators aren't applied polymorphically - so when you use == between two objects (no matter what their *real* type) you're actually using Object's == operator, not bool's. Object's == operator compares the reference; the two bools have been boxed onto the heap and have different references.

Methods, however, are applied polymorphically so because the object is *really* a bool, when we call Equals() we call bool's override. Which as you can see, works a treat.

It's really easy to forget this. We'd much rather be writing a == b because it reads better andthis is fine if you know what types you are dealing with at design time. A good example of when care needs to be take is when using reflection. Naturally, when reflecting we have no idea what types we're dealing with at design time so we tend to be using Object a lot. This caught me out just yesterday (thank heavens for unit tests) - it's nice to be reminded of the fundamentals don't you think?

In such cases, or a million others (where a parameter may have been subclassed for example) think carefully about using a.Equals(b) instead.

One thing to watch out for

There is of course one problem with that last code snippet:

a.Equals(b);

What if 'a' is null? Fortunately, the nice chaps at .NET land thought of this and kindly provided us with a static .Equals method on the object class which helps out here. Here's the implementation (courtesy of reflector).

public static bool Equals(object objA, object objB)
{
    if (objA == objB)
    {
        return true;
    }
    if ((objA != null) && (objB != null))
    {
        return objA.Equals(objB);
    }
    return false;
}

So, if 'a' could be null, why not use

object.Equals(a, b);
    
Ah, thank you .NET land.

Tags: .NET

 
Josh Post By Josh Twist
12:39 AM
10 Nov 2006

» Next Post: Nice usage of AJAX
« Previous Post: How to test if a Type supports nulls

Comments are closed for this post.

© 2005 - 2017 Josh Twist - All Rights Reserved.