53

When I implement objects that I want to compare using the IEquatable<T> interface:

  1. Why do I have to override Equals(object) method if I already implemented Equals(T)?
  2. Can I use == and != operators once I implement IEquatable<T>?
Palec
  • 12,743
  • 8
  • 69
  • 138
leora
  • 188,729
  • 360
  • 878
  • 1,366

2 Answers2

53
  1. From MS Docs article on IEquatable<T>:

    If you implement IEquatable<T>, you should also override the base class implementations of Equals(Object) and GetHashCode() so that their behavior is consistent with that of the Equals(T) method. If you do override Equals(Object), your overridden implementation is also called in calls to the static Equals(Object, Object) method on your class. In addition, you should overload the op_Equality and op_Inequality operators. This ensures that all tests for equality return consistent results.

  2. No, operators do not use the Equals method. They must be overloaded separately to do so.

Palec
  • 12,743
  • 8
  • 69
  • 138
Ray Booysen
  • 28,894
  • 13
  • 84
  • 111
  • so when you are dealing with objects, is == assumed to only mean the exact same memory address (same instance) – leora Jan 04 '09 at 19:21
  • Pretty much. More info here: http://msdn.microsoft.com/en-us/library/53k8ybth(VS.80).aspx – Ray Booysen Jan 04 '09 at 19:23
  • 8
    No, use ReferenceEquals() for that purpose. The equality operator (==) usually means the same, but can be overriden (e.g. for Strings and the like). – Paul-Jan Jan 04 '09 at 19:26
  • 13
    Slight terminology correction - you can't *override* operators, but you can *overload* them. – Jon Skeet Jan 04 '09 at 19:33
  • 2
    Yes, you can overload == and != in and use them in conjunction with the IEquatable interface. But this needs to be done manually, it doesn't come automatically with IEquatable. The "No" in part 2 of the answer is actually incorrect. Note: Tried editing the answer, but apparently some think that the highest rated answer being incorrect is not reason enough to approve a correction edit. – AlexKven Aug 25 '16 at 17:19
  • @AlexKven Done! It's not that such an edit shouldn't be made; it's that you're expecting reviewers to re-do your own research, to verify your change. Sometimes, they may not even be familiar with the programming language in question. – jpaugh Sep 11 '18 at 17:11
44

1) As Ray said, override Equals(object) to ensure consistency when the method is called from classes which don't know (statically) that you implement IEquatable<T>. For instance, the non-generic collections classes will use Equals(object) for comparisons. You should also override GetHashCode().

2) Implementing IEquatable<T> doesn't overload the == and != operators automatically, but there's nothing to stop you from doing so, just like System.String does. You should document this very clearly if you do, however - and be careful when you make comparisons between other types of reference (e.g. MyType and Object) which will still use the identity comparison. I suspect it's not a great idea to do this unless it's going to be a very heavily used type in your code, where everyone will become very familiar with it and where the syntactic sugar of overloading == will really make a positive impact on readability.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Jon, is there any performance gain for an IEquatable implementing type used for instance in a Collection, calling the Contains method? – Rauhotz Jan 04 '09 at 20:04
  • 7
    It will avoid casting, yes. For value types, it'll avoid boxing and unboxing as well. See the docs for Collection.Contains - it uses EqualityComparer.Default, which will use the IEquatable implementation if possible. – Jon Skeet Jan 04 '09 at 20:12
  • 6
    Yes, it is not a good idea to overload operator == and != to provide value equality checks (vs the default reference equality check). The MSDN documentation suggests you only do it for immutable types. There are also issues involving interfaces and operator overloading. – Zach Burlingame Apr 08 '09 at 16:16
  • 1
    See http://stackoverflow.com/questions/728434/operator-overloading-with-interface-based-programming-in-c for more on both issues. – Zach Burlingame Apr 08 '09 at 16:16