为什么比较运算符没有自动重载为IComparable?

7
当一个类实现了 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) { /*...*/ }

我们知道CompareTo的实现使得obj1 < obj2 == true,但是由于未重载<运算符,这将不起作用。(我知道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 上默认工作呢?


最有可能是因为实际结果会令人困惑(不是在您的特定情况下,而是总体上),例如 class MyComparable : IComparable<MyComparable>,IComparable<int>, IComparable<string> 将是一个有趣的案例。对于一般的“为什么语言没有这个功能”的问题,请查看 minus 100 points 文章。 - Alexei Levenkov
请查看 https://github.com/dotnet/roslyn/issues/8633。 - MotKohn
2个回答

10
当一个类实现了IComparable接口,我们就可以通过CompareTo方法来重载<、>和==操作符,是吗?
没错。
我理解你的不满。这也是我对C#感到不满的十件事中排名第九的原因之一。

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

那么为什么不自动重载这些内容呢?

功能不会默认实现,必须有理由才能移除它们。相反,需要设计、规定、实现、测试、文档化和发布功能。如果其中一件事情没有完成,就不会有这个功能。

你期望的功能没有完成上述活动中的任何一项。该功能已被提出,但从未接近语言设计团队时间最佳使用列表的顶部。

如果您非常想要这个功能,您可以在Roslyn Github论坛上提出,并且也许有朝一日它将被实现。


1

这个功能在Roslyn Github论坛上已经有提案了。它被关闭有两个原因:

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

有一个Nuget包可以实现OP所需的功能,但我没有测试过。 https://www.nuget.org/packages/Exts.Comparisions.Classes.Operators/


我理解改变“==”运算符的行为所带来的问题,但是是否有任何原因不能将这种改变应用于“<”,“>”,“<=”和“>=”运算符? - Duncan Lukkenaer
@mrlucks 请查看上面的提案链接。你的论点已经在那里阐述了。我认为最终的推理是我先前提到的原因。 - MotKohn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接