19

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,104
  • 5
  • 46
  • 92

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
  • 103,479
  • 23
  • 206
  • 257
  • 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
  • 128,537
  • 12
  • 134
  • 188
3

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

Community
  • 1
  • 1
Albireo
  • 10,642
  • 13
  • 60
  • 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
0

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://docs.microsoft.com/dotnet/csharp/tutorials/default-interface-methods-versions

-1

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

MattDavey
  • 8,641
  • 3
  • 30
  • 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