Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing IEquatable<T> where T is an interface

I have a domain model that is trivially represented by the following.

IMyInterface

ClassA : IMyInterface

ClassB : IMyInterface

What I want is to implement IEquatable in such a way that I can write code something like.

if(dynamicallyCreatedInstanceOfClassA == dynamicallyCreatedinstanceOfClassB)
{
  // Do something relevant
}

My first inclination was to have IMyInterface implement IEquatable but of course I can't actually do the implementing in IMyInterface. I would have to do that in ClassA and ClassB. What strikes me as wrong with this solution is that the implementations of IEquatable in ClassA and ClassB will be exactly, line for line the same. Is there an elegant way to accomplish this? When ClassC comes along I don't want to have to copy and past 50 lines of duplicated IEquatable code.

I have considered using an abstract base class instead of an interface, but in this scenario IMyInterface really just describes actions the class will perform and not what the class is. ClassA and ClassB don't share many similarities except they can both perform the actions in the IMyInterface contract.

Any insights are helpful, and thank you for your time.

like image 415
Matthew Vines Avatar asked Sep 30 '09 15:09

Matthew Vines


People also ask

When should you implement IEquatable?

In . NET you implement IEquatable if you want to modify equality of structs (not to forget implementing GetHashCode , == , != ) to go along with it.

Does INT implement IEquatable?

Just take the above example, int implements the IEquatable<int>. Likewise, the other primitive types also implement IEquatable<T>. Generally, IEquatable<T> is very useful for the value types.

What is IEquatable in C#?

The IEquatable<T> interface is used by generic collection objects such as Dictionary<TKey,TValue>, List<T>, and LinkedList<T> when testing for equality in such methods as Contains , IndexOf , LastIndexOf , and Remove . It should be implemented for any object that might be stored in a generic collection.


2 Answers

Instead of implementing IEquatable<T>, could you perhaps implement IEqualityComparer<T> in a separate class? In most cases where you're interested in equality you can specify a comparer instead, and I suspect it'll be cleaner that way.

like image 186
Jon Skeet Avatar answered Sep 20 '22 15:09

Jon Skeet


Based on your question it seems like you know what the Equals algorithm will be and that it will be the exactly the same for both ClassA and ClassB. Why not do the following

  1. Define IMyInterface to inherit from IEquatable<IMyInterface>
  2. Define an abstract base class MyInterfaceBase which implements IMyInterface and has the IEquatable<IMyInterface> implementation
  3. Have ClassA and ClassB derive from MyInterfaceBase
like image 22
JaredPar Avatar answered Sep 24 '22 15:09

JaredPar