10

I have a class. The thing that this class is meant to represent is such that we may speak about such things being equal to each other, and we may also come up with a scheme to rank them for purposes of comparison.

However, it so happens that it is rare that one feels the need to rank these things, but one often needs to check if two such things are equal.

So, I can implement both IEquatable for my class as well as IComparable. While IComparable provides some extra functionality, it is very unlikely that anyone will care about this extra functionality. Neither one seemingly provides a clear advantage, either logically or functionality-wise.

Which interface should I implement, IEquatable, IComparable, or both? Why? (I am specifically wondering about framework-wide implications either interface)

This question is similar, but the answers only state the obvious, which doesn't help me.

In case you are wondering, the class is meant to represent a nucleotide. Nucleotides can readily be equated, but they can also be compared (eg. alphabetically).

Community
  • 1
  • 1
Superbest
  • 25,318
  • 14
  • 62
  • 134
  • Is there ever a possibility that you'd need to sort them? I know you said that it's unlikely, but if you were to give the class to someone else can you think of a reason they'd ever need to sort? – JNYRanger Jan 18 '14 at 00:33
  • I'm certain that it's possible to come up with a contrived scenario in which one might need to alphabetically sort them (for producing human-readable output with nice formatting) or perhaps sort them by some biochemical property (like mass). But it would be contrived, and if I were to implement `IComparable`, I would have to write documentation (without it the method would be useless) for methods that would very rarely be used. – Superbest Jan 18 '14 at 00:40

4 Answers4

9

I would definitely implement IEquatable<T> but skip IComparable/IComparable<T> for now.

As you said there is no one way to compare nucleotides. Someone may need to compare them alphabetically, someone may need another way to sort them. I would rather provide different implementations of IComparer<Nucleotide> to implement IComparable/IComparable<T> itself.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • 1
    There is no non-generic `IEquatable`, as if there was it would just match the `Equals()` override all objects have. That said, one must always override `Equals()` and `GetHashCode()` appropriately when one does implement `IEquatable`, so your point holds. – Jon Hanna Jan 18 '14 at 02:30
3

It is primarily opinion based but I would not implement IComparable if comparability is not obvious (like in number). If someone would like to sort Nucleotides, for example, it can provide its own IComparer implementation. As a library author I would provide a set of possible IComparers, for example to sort them alphabetically as you said.

Konrad Kokosa
  • 16,563
  • 2
  • 36
  • 58
3

If the objects are inherently comparable then I would do the extra work and implement IComparable<T> on top of IEquatable<T>. As the author of the type you are in the best position to provide the correct implementation. Leaving it to another developer to implement increases the chance of the following happen

  • Them implementing comparison incorrectly. Other developers will likely be less familiar with the data than you and hence more likely to miss corner cases
  • Duplicate cadoe. If you don't provide the defacto comparison then every developer will separately have to do it themselves leading to duplicate code
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • If other developers each implement their own comparison, then communication at that organization is pretty poor :-/ – Matt Greer Jan 18 '14 at 00:39
  • @MattGreer whose to say they work at the same company? Perhaps this code becomes more widely used and you have developers at diff companies using it – JaredPar Jan 18 '14 at 00:41
  • @MattGreer To be sure, in my particular case, the other developers are (if any) "me in the distant future". – Superbest Jan 18 '14 at 00:42
  • 2
    @MattGreer "then communication at that organization is pretty poor". In other words, a typical organization. :-) – RenniePet Jan 18 '14 at 00:43
1

You should implement the interface that gives you what you need now. If you later find that IComparable is something you need, implement it then.

It can be tough to decide how much future proofing to do. But when adding the additional future feature is relatively simple, I always opt to not do them. You may find you never need IComparable, and even if it's a tiny addition, it still requires maintenance and consideration.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • More to the point, `IComparable` before it's clear how it's needed is anti-future-proofing, because if a later requirement for a given means of comparison doesn't match it, it would be a breaking change to change the current implementation. – Jon Hanna Jan 18 '14 at 02:32