在C#中重载运算符<

3
我有以下代码:

我有以下代码:

public class Foo
{
    public static bool operator<(Foo l, Foo f)
    {
        Console.WriteLine("Foo!");
        return false;
    }
    //public static bool operator>(Foo l, Foo f)
    //{
    //    return f < l;
    //}
}

编译器报错信息如下:

运算符“Program.Foo.operator <(Program.Foo, Program.Foo)”需要定义匹配的运算符“>”

这对我来说很奇怪。为什么我要重载 operator> 运算符呢?


6
为什么这很奇怪?如果你定义了obj1小于obj2的情况,那么你也应该定义obj1大于obj2的情况。 - Tim Schmelter
6
我认为同时重载两者才是“奇怪”的。如果发现a < bb > a结果不同,那肯定会让我感到惊讶。 - Charles Mager
3
如果你有一个小于运算符,那么你也应该有一个大于运算符。如果你的 < 运算符不表示“小于”,那么你可能不应该使用它,而应该使用一个方法代替。运算符应该具有明确的含义。 - Dennis_E
1
"但是我永远不能使用操作符 >" - 也许你现在不知道,但这种情况会一直存在吗?其他人在编写代码时可能会使用它。你打算怎么办?难道要去拆掉每个人键盘上的 > 键,以防止他们在你的代码中使用吗? - user585968
1
@LmTinyToon,你能展示一下实际的代码吗,这样我们才能理解为什么你只想要“<”? - juharr
显示剩余15条评论
4个回答

4
因为该操作符是成对出现的(如 == 和!= )。 它希望您实现两者以确保您不会意外忘记它。 如果您说 < 的行为不同,那么 > 也应该如此,因此您被迫过载它。
正如MSDN所说:
用户定义的类型可以重载 < 运算符。 如果类型重载“小于”运算符 < ,则它必须同时重载“大于”运算符 > 。

看起来 MSDN 页面现在已经更新了,不再提到这个问题了。但对我而言,这句话本身听起来更像是在一般讨论其他二元操作符,比如重载二元加号操作符也会隐式地重载 '+=' 操作符(而当比较操作符成对出现时,则不是隐式的,而是必须明确)。似乎这个注释不适用于比较操作符(因为它们没有等效的赋值操作符),这可能是它不再包含在页面上的原因。 - NotEnoughData
1
@NotEnoughData 已更新为最新文档,仍然支持我的答案。 - Patrick Hofman

2
我可以翻译成中文:
我可以推测的原因是由于不等式运算符的数学属性。> 是 < 的反向。
如果编译器假定这些属性并且允许交换其中一个,那也就不足为奇了。即使编译器不能这样做,生成的代码也将难以管理。
例如,以重构工具为例——在这些工具中,反转运算符是相当常见的功能。

1
如果我没记错的话,">="是"<"的倒数。不过你说的也没错。 - CSharpie
似乎逆运算符<仍然是>(请参见维基百科):a<b等同于b>a。然而,(a>b)的相反操作是(a<=b)。然而,这对于可空类型不起作用... - bushed

1

来自可重载运算符

比较运算符如果被重载,必须成对被重载;也就是说,如果重载了 ==,则 != 也必须被重载。

反之亦然,对于 < 和 > 同样适用,以及 对于 <= 和 >=。


1
这是比较运算符重载的规则。你只能成对地重载这些运算符:
  • ==!=
  • <>
  • <=>=

如果重载比较运算符,则必须成对重载;也就是说,如果重载了 ==,那么 != 也必须被重载。反之亦然,< 和 > 以及 <= 和 >= 的情况也类似。

MSDN Source - Overloadable Operators (C# Programming Guide)


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