Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are the comparison operators not automatically overloaded with IComparable?

When a class is IComparable, then we know everything to overload the <, > and == operators due to the CompareTo functionality, right? Then why aren't these overloaded automatically?

Take a look at the example below:

public class MyComparable : IComparable<MyComparable>
{
    public int Value { get; }
    public MyComparable(int value) { Value = value; }

    public int CompareTo(MyComparable other) => Value.CompareTo(other.Value);
}

I was wondering why something like this wouldn't work by default:

MyComparable obj1 = new MyComparable(1),
             obj2 = new MyComparable(2);

if (obj1 < obj2) { /*...*/ }

We know that obj1 < obj2 == true because of our implementation of CompareTo, but because the < operator is not overloaded, this will not work. (I know that obj1.CompareTo(obj2) < 0 will give the desired result, but that's less obvious in most cases.)

Only when I add the code below to the class, it will work the way I expected:

public static bool operator <(MyComparable x, MyComparable y) => x.CompareTo(y) < 0;
public static bool operator >(MyComparable x, MyComparable y) => x.CompareTo(y) > 0;

// And for equality:
public static bool operator !=(MyComparable x, MyComparable y) => !(x == y);
public static bool operator ==(MyComparable x, MyComparable y)
{
    if (ReferenceEquals(x, y)) return true;
    if (((object) x == null) || ((object) y == null)) return false;
    return x.CompareTo(y) == 0;
}

This is very generic functionality, so what's the reason these comparisons don't work by default on every IComparable?

like image 757
Duncan Luk Avatar asked Oct 04 '16 19:10

Duncan Luk


2 Answers

When a class is IComparable, then we know everything to overload the <, > and == operators due to the CompareTo functionality, right?

Yep.

I share your frustration. Your complaint is number nine on my list of ten things that irritate me about C#.

http://www.informit.com/articles/article.aspx?p=2425867

Then why aren't these overloaded automatically?

Features are not implemented by default and have to have reasons to remove them. Rather, features need to be designed, specified, implemented, tested, documented and shipped. If one of those things doesn't happen, no feature.

None of those things happened for your desired feature. The feature has been proposed but never got anywhere close to the top of the list of best uses for the language design team's time.

If you want this feature badly enough you can always pitch it at the Roslyn Github forum and maybe it will be implemented someday.

like image 90
Eric Lippert Avatar answered Nov 14 '22 21:11

Eric Lippert


There is a proposal already on the Roslyn Github forum for this feature. It was closed for two reasons:

  • First: It might break someone's code if it was not implemented the "obvious" way.
  • Second: by default the == operator compares by reference changing it to CompareTo will break code.

There is a Nuget package that is supposed to do as OP desires, I did not test it. https://www.nuget.org/packages/Exts.Comparisions.Classes.Operators/

like image 37
MotKohn Avatar answered Nov 14 '22 21:11

MotKohn