Overriding the equality operators

I’ve always found it rather painful to correctly override the equality operators in a class file. I always end up with cyclic references, stack overflows, null pointers, or other problems that are equally terrible. So finally today I sat down and figured out how to do it “correctly” – whereby “correctly” I mean, “in a way that gives me the right result without throwing an exception.

My model here is a very simple class called SimpleResponse. The class is generic (must be a primitive type, i.e. struct) and only has two fields: Value (of type T), and Description (of type String). Here’s how I did the equality overloads:


// Instance method
override public bool Equals(object obj) {
    return Equals(this, obj as SimpleResponse<T>);
}

static public bool operator ==(SimpleResponse<T> first, SimpleResponse<T> second)
{
    return Equals(first, second);
}

static public bool operator !=(SimpleResponse<T> first, SimpleResponse<T> second)
{
    return !Equals(first, second);
}

static public bool Equals(SimpleResponse<T> first, SimpleResponse<T> second)
{
    if (ReferenceEquals(first, null) && ReferenceEquals(second, null)) return true;
    if (ReferenceEquals(first, null) || ReferenceEquals(second, null)) return false;

    return Object.Equals(first.Value, second.Value) &&
        String.Equals(first.Description, second.Description);
}

The important things to note here are:

  1. All the equality methods effectively just delegate to the Equals method right down the bottom.
  2. Since you’re overriding the == and != operators, you cannot use these in your Equals method to calculate equality – this will cause a StackOverflowException. This includes checking for null – note that you have to use ReferenceEquals instead (which is a static method on the Object class).
  3. Similarly, you can’t use the Equals method without causing a StackOverflowException. If you need to use an Equals method, you need to explicitly state which Object implements the method you want to use -note here I’m using String.Equals for comparing the descriptions, and Object.Equals when I can’t tell the type of the variable.

If anyone has suggestions as to a way I could have done this better, I’d love to hear them!

Posted in .Net, C#, Uncategorized by Gerrod at July 6th, 2007.

2 Responses to “Overriding the equality operators”

  1. viiviiviivii says:

    Doesn’t this kind of stuff make it more confusing for subsequent developers to maintain your code?

  2. gerrod says:

    No, I don’t really think so – especially because I’m delegating all of the equality methods to the final one, so there’s only a single “point of failure”.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Quickduck logo