Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Object.Equals

Two questions about Equals:

(1)  As I test Object.Equals(objA As Object, objB As Object), it appears that it returns the value of objA.Equals(objB).  But I'd like to find documentation to confirm this for my peace of mind.  Does anyone know of any?

(2)  What terrible consequences could come about if I fail to override GetHashCode when I override Equals?

Kyralessa
Friday, December 31, 2004

Never mind on (2); after some reading and a few epiphanies I now understand what hashcodes are for, and I now have an easy way to implement them in my objects.

But still wondering about (1).

Kyralessa
Friday, December 31, 2004

The static overload returns true if you supply two null references. The instance overload always requires the first instance to be non-null, so it can't do that. Other than that, they should be exactly identical.

Chris Nahr
Saturday, January 01, 2005

By the way, casting to Object is pointless for the static overload. System.Object.Equals takes two Object parameters, so the casts are performed automatically if necessary.

Chris Nahr
Saturday, January 01, 2005

PS: Go read Jeff Richter's "Applied MS .NET Framework Programming", and make sure to check the errate on his website, too. He writes extensively about equality checks and other tricky areas in .NET.

Chris Nahr
Saturday, January 01, 2005

I can't imagine when there'd ever be a point in casting to Object.  But mostly I was wondering if there was any point in overriding that version of Equals.  It's pretty clear now that there's not.  Thanks!

Funny you should mention that book; I've had a request in to the library for it for a few weeks now, but there's still one in front of me.  Good to know that it'll be helpful.

Kyralessa
Saturday, January 01, 2005

No, you *MUST* override the instance overload of Object.Equals! You must check the argument for type identity (not just compatibility) with the type on which you're overriding Equals. If the argument type is identical to the current type, you should then pass over to the strongly typed implementation of Equals. Richter explains all that.

Chris Nahr
Saturday, January 01, 2005

Also, if you're truly interested in this stuff get yourself a copy of Reflector.
http://www.aisto.com/roeder/dotnet/



Here is the decompiled output for the static overload of Object.Equals:

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 as you see, the static overload returns the result of the instance overload except in the case of reference equality or null references.

Chris Nahr
Saturday, January 01, 2005

I guess saying "that version" was a bit vague; what I meant was that I had already overridden the instance version of Equals, but wasn't sure whether I needed to override the shared version as well.  (Actually, looking back at the docs now, they're more clear than I thought they were; perhaps it was just the end of a long workweek.)

Kyralessa
Saturday, January 01, 2005

You can't override a static/shared method. You could if you were programming Smalltalk, but in the .NET Framework that's impossible.

Chris Nahr
Saturday, January 01, 2005

public static bool Equals(object objA, object objB)
{
>>>    if (objA == objB)

So how does the compiler know to do the right thing here and compare the pointer values as opposed to recursively calling the static overloaded equality function again to do the comparison?

Or do you have to right this function in IL directly?

Rob Walker
Friday, January 07, 2005

==, Equals, and ReferenceEquals are all independent methods.

Brad Wilson
Friday, January 07, 2005

Rob, when you redefine operator== you do normally call your redefinition of Equals on the same type.

However, the System.Object implementation of operator== is not explicitly defined. Instead, it implicitly translates to the IL opcode that does a reference comparison.

That's also a great trick when you want to make sure to compare references, rather than invoke some custom operator== definition: simply cast both operands to Object before comparing.

Chris Nahr
Saturday, January 08, 2005

*  Recent Topics

*  Fog Creek Home