Possible Duplicate:
How do I check for nulls in an ‘==’ operator overload without infinite recursion?
There is probably an easy answer to this...but it seems to be eluding me. Here is a simplified example:
public class Person
{
public string SocialSecurityNumber;
public string FirstName;
public string LastName;
}
Let's say that for this particular application, it is valid to say that if the social security numbers match, and both names match, then we are referring to the same "person".
public override bool Equals(object Obj)
{
Person other = (Person)Obj;
return (this.SocialSecurityNumber == other.SocialSecurityNumber &&
this.FirstName == other.FirstName &&
this.LastName == other.LastName);
}
To keep things consistent, we override the == and != operators, too, for the developers on the team who don't use the .Equals
method.
public static bool operator !=(Person person1, Person person2)
{
return ! person1.Equals(person2);
}
public static bool operator ==(Person person1, Person person2)
{
return person1.Equals(person2);
}
Fine and dandy, right?
However, what happens when a Person object is null
?
You can't write:
if (person == null)
{
//fail!
}
Since this will cause the == operator override to run, and the code will fail on the:
person.Equals()
method call, since you can't call a method on a null instance.
On the other hand, you can't explicitly check for this condition inside the == override, since it would cause an infinite recursion (and a Stack Overflow [dot com])
public static bool operator ==(Person person1, Person person2)
{
if (person1 == null)
{
//any code here never gets executed! We first die a slow painful death.
}
return person1.Equals(person2);
}
So, how do you override the == and != operators for value equality and still account for null objects?
I hope that the answer is not painfully simple. :-)
Cast the
Person
instance toobject
:cdhowie is on the money with the use of
ReferenceEquals
, but it's worth noting that you can still get an exception if someone passesnull
directly toEquals
. Also, if you are going to overrideEquals
it's almost always worth implementingIEquatable<T>
so I would instead have.And of course, you should never override
Equals
and not overrideGetHashCode()
It's also worth noting that identity entails equality (that is, for any valid concept of "equality" something is always equal to itself). Since equality tests can be expensive and occur in loops, and since comparing something with itself tends to be quite common in real code (esp. if objects are passed around in several places), it can be worth adding as a shortcut:
Just how much of a benefit short-cutting on
ReferenceEquals(this, other)
is can vary considerably depending on the nature of the class, but whether it is worth while doing or not is something one should always consider, so I include the technique here.Easier than any of those approaches would be to just use
This has the same null equality semantics as the approaches that everyone else is proposing, but it's the framework's problem to figure out the details :)
Cast the Person to an Object and then perform the comparison:
The final (hypothetical) routine is below. It is very similar to @cdhowie's first accepted response.
Thanks for the great responses!
//* -
.Equals()
performs the null check on person2I've always done it this way (for the == and != operators) and I reuse this code for every object I create:
"!=" then goes like this:
Edit
I modified the
==
operator function to match Microsoft's suggested implementation here.