20

I have an interface like this:

public interface IFoo
{
  int A {get;}
  int B {get;}
}

and I have multiple classes implementing IFoo.
I want to check equality, not based on ReferenceEquality, but two IFoos should be considered equal, if both A and B is the same (in reality I'm checking a collection of Key-Value pairs sent through WCF, that is why I can't have ReferenceEquality).
Now if I have:

IFoo first = new FooBar1() { A = 1, B = 1};
IFoo second = new FooBar2() { A = 1, B = 1};
if (first == second) {
 //this should return true
}

Currently IFoo is IEquatable<IFoo>, so FooBar1 and FooBar2 overrides Equals(IFoo other), but that's not what gets called on ==. I'm hunting through my code to replace a==b with a.Equals(b) everywhere, but that's just not nice.

What can I do?

TDaver
  • 7,164
  • 5
  • 47
  • 94

5 Answers5

25

No, you can't. Overloading == requires static methods in one of the types you use, and an interface can't contain those. Extension methods can't help either. So on interfaces == is always using reference equality.

Note that a.Equals(b) will throw an exception if a==null.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • 1
    yeah, for that I already wrote an EqualsWithNull extension, that returs true for a.EqualsWithNull(b)... – TDaver Feb 21 '11 at 14:05
  • 2
    @TDaver or you could use `Object.Equals(a, b)`, which - since every type inherits Object - can be shortened to just `Equals(a, b)` – MattDavey Dec 17 '15 at 00:04
6

No, you can neither overload an operator on an interface, nor ensure that any implementors do so (as operator overloading is static in C# ).

Your best option is what you've done, to make IFoo inherit from IEquatable<IFoo> and use Equals(IFoo)

Jamiec
  • 133,658
  • 13
  • 134
  • 193
3

Besides CodeInChaos' answer you may be interested in reading Guidelines for Overriding Equals() and Operator ==.

Community
  • 1
  • 1
Albireo
  • 10,977
  • 13
  • 62
  • 96
  • 1
    But note that it says to overload `operator ==` and `operator !=` when the type is immutable. So have interface (multiple types same interface but different semantics all immutable) need to use abstract base rather than interface so I can override operators when other types return mixed collections. In the end: hitting limits of the CLR type system (again :-( ). – Richard Mar 04 '14 at 17:31
-1

Since introduction of C# 8 you can provide interfaces with default implementations and static methods (which allows you o define operators for interfaces)

More here: https://learn.microsoft.com/dotnet/csharp/tutorials/default-interface-methods-versions

  • I was really interested in this, but the link is broken. Consider updating it -- also, when you post links to articles it's a good idea to paste a bit of the article into your answer so even if the article is taken down your answer is still valid. – Anthony Nichols Jul 18 '22 at 13:54
-2

What you're talking about here is an implementation detail, a Interface should not (cannot) define how it is implemented.

MattDavey
  • 8,897
  • 3
  • 31
  • 54
  • 2
    You're not wrong, but your answer is closer to a comment. This was not a 'why' question. (Just a guess, I did not vote.) – piedar Dec 16 '15 at 21:20