Implementing the IComparable Interface

I'm reading the book c#6.0 in a Nutshell now, the code below is on topic "Implementing the IComparable Interfaces".

I don't get a few things:

  1. Why the IComparable.CompareTo is implemented explicitly there ?
  2. What if it would be just another implicit overload of CompareTo (one implicit int CompareTo (Note other), another one implicit int CompareTo (object other) ?
public struct Note : IComparable<Note>, IEquatable<Note>, IComparable
   int _semitonesFromA;
   public int SemitonesFromA { get { return _semitonesFromA; } }

   public Note (int semitonesFromA)
     _semitonesFromA = semitonesFromA;

   public int CompareTo (Note other) // Generic IComparable<T>
   if (Equals (other)) return 0; // Fail-safe check
   return _semitonesFromA.CompareTo (other._semitonesFromA);

   int IComparable.CompareTo (object other) // Nongeneric IComparable
   if (!(other is Note))
   throw new InvalidOperationException ("CompareTo: Not a note");
   return CompareTo ((Note) other);

   public static bool operator < (Note n1, Note n2)
     => n1.CompareTo (n2) < 0;

   public static bool operator > (Note n1, Note n2)
     => n1.CompareTo (n2) > 0;

   public bool Equals (Note other) // for IEquatable<Note>
     => _semitonesFromA == other._semitonesFromA;

   public override bool Equals (object other)
   if (!(other is Note)) return false;
   return Equals ((Note) other);

   public override int GetHashCode() => _semitonesFromA.GetHashCode();
   public static bool operator == (Note n1, Note n2) => n1.Equals (n2);
   public static bool operator != (Note n1, Note n2) => !(n1 == n2);
Jon Skeet

You could implement IComparable implicitly, yes. But fundamentally you want to try to discourage users from comparing a Note with anything other than another Note. You may have legacy usages if IComparable, but if anything knows about the Note class directly, you don't want to allow:

Note note = new Note();
Other other = new Other();
int result = note.CompareTo(other);

You know that that's always going to throw an exception, so why allow it at all? Basically, regard the non-generic IComparable interface as "somewhat legacy" (there are valid uses, but...) and discourage anyone from using it by implementing it explicitly.


See more on this question at Stackoverflow