A pattern for implementing the == operator in C#

I’ve been neglecting this blog for a while because I have very little time to write here…

Every now and then I need to implement the == operator on one of my classes; typically because I want to compare two instances of a custom type that can’t be compared automatically. So I always copy and paste more or less the same code. I figured I may as well share it. This is, of course, an oversimplified example. It’s just intended to show the pattern.

In the code that follows, the pattern is quite simple:

  1. Implement a public Equals method that takes a parameter of the same type as your class. In that method, compare whatever it is you consider a reasonable representation of equality between instances. (In this trivial example, I just compare properties. You might want to do something more, but try not to do anything overly complex. Nobody expects the code to perform processor-intensive calculations while comparing two objects.)
  2. Override object.Equals and internally call your strongly typed method if the object passed is of the same type; otherwise return false (because you don’t compare apples and oranges).
  3. Override the == and != operators, which need only call your strongly typed Equals method.
  4. Since you implemented == and !=, you should also override object.GethashCode.

Here’s the code:

namespace EqualsExample
{
    public class Example
    {
        public int Number { get; set; }
        public string Text1 { get; set; }
        public string Text2 { get; set; }

        public static bool operator !=(Example example1, Example example2)
        {
            return !example1.Equals(example2);
        }

        public static bool operator ==(Example example1, Example example2)
        {
            return example1.Equals(example2);
        }

        public override bool Equals(object obj)
        {
            var other = obj as Example;

            if (other != null)
                return this.Equals(other);

            return false;
        }

        public bool Equals(Example other)
        {
            return this.Text1 == other.Text1 && this.Text2 == other.Text2 && this.Number == other.Number;
        }

        public override int GetHashCode()
        {
            return this.Text1.GetHashCode() ^ this.Text2.GetHashCode() ^ this.Number;
        }
    }
}

One thing that’s worth pointing out is the first line of the overridden object.Equals method, which uses the as operator to cast to the appropriate type. That will return null if the object is not the correct type. If you were writing a value type (and Example was a struct rather than a class), you could not use the as operator, and would have to do this:

var other = (Example)obj;

Then again, maybe you don’t want the code to throw an InvalidCastException… Then use the is operator. I don’t because I don’t want to cast twice, and I tend not to pass the wrong types for comparison in my own code.

Advertisements

About Jerome

I am a senior C# developer in Johannesburg, South Africa. I am also a recovering addict, who spent nearly eight years using methamphetamine. I write on my recovery blog about my lessons learned and sometimes give advice to others who have made similar mistakes, often from my viewpoint as an atheist, and I also write some C# programming articles on my programming blog.
This entry was posted in Programming and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s