为什么比较运算符不会自动超载IComparable?

时间:2016-10-04 19:44:55

标签: c# comparison operator-overloading

当一个班级为IComparable时,由于<功能,我们知道所有要重载>==CompareTo运算符的一切,对吧?那为什么这些不会自动重载?

看一下下面的例子:

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

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

我想知道为什么这样的事情默认不起作用:

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

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

由于obj1 < obj2 == true的实施,我们知道CompareTo,但由于<运算符未重载,因此无效。 (我知道obj1.CompareTo(obj2) < 0会给出所需的结果,但在大多数情况下这不太明显。)

只有当我将下面的代码添加到课程中时,它才会按照我的预期运作:

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;
}

这是非常通用的功能,那么这些比较在每个IComparable上默认不起作用的原因是什么?

2 个答案:

答案 0 :(得分:9)

  

当一个类是IComparable时,我们知道所有重载&lt;,&gt;和CompareTo功能导致的==运算符,对吧?

是的。

我分享你的沮丧。你的投诉在我列出的关于C#的十件事情中排名第九。

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

  

那为什么这些不会自动重载?

默认情况下不会实现功能,必须有理由将其删除。相反,需要设计,指定,实施,测试,记录和发送功能。如果其中一件事没有发生,那就没有特色了。

这些事情都没有发生在你想要的功能上。该功能已被提出,但从未接近语言设计团队最佳使用时间列表的顶部。

如果你想要这个功能非常糟糕,你可以随时在Roslyn Github论坛上进行推广,也许有一天它会实现。

答案 1 :(得分:0)

Roslyn Github论坛已经有proposal用于此功能。它被关闭有两个原因:

  • 首先:如果没有以“明显”的方式实施,可能会破坏某人的代码。
  • 第二:默认情况下,==运算符按引用进行比较,将其更改为CompareTo会破坏代码。

有一个Nuget包应该像OP那样做,我没有测试它。 https://www.nuget.org/packages/Exts.Comparisions.Classes.Operators/