在C#中重载运算符实际上是一种好的实践吗?

5
作为刚接触C#的新手,我知道运算符重载的目的和用途,并且我可以看到在某些特定情况下它有时非常优雅,比如通过否定值对象来一次否定所有字段,然而这种事情总是可以用简单、直接的方法来实现。是否有一些标准可供参考,什么时候或者是否应该重载运算符,什么时候应该只使用方法?我没有找到任何类似的东西,所以这只是口味/编程范式/风格的问题吗?

1
我从未听说过任何指南描述如何在操作符和方法之间进行选择。但是,使用C#和.Net几年后,我很少看到操作符被重载(除了==和!=)。 - Sergey.quixoticaxis.Ivanov
1
如果我能想到的其他解决方案都非常荒谬,我当然会这样做。不要说永远,但在十年的 C# 专业编程生涯中,我不能回忆起有过这样的情况。 - 15ee8f99-57ff-4f92-890c-b56153
2
我认为这主要是个人偏好的问题。我们的C#代码库有一些核心几何类型(向量、点、方向),它们有重载运算符来支持叉积/点积、变换等操作。我认为对于像这样的基本数据类型,这是有意义的,但在大多数情况下应该避免使用。 - E. Moffat
3
如果你在编写算术原语(如有理数、复数或向量/矩阵类型),强制用户使用静态方法来描述简单的变换很快就会变得笨重。p0 = r * u - Axis + origin;p0 = Point.Add( Vector.Subtract( Vector.Multiply( r, u ), Axis ), origin ); 更易读。除了代数上下文之外,我唯一使用过运算符重载是在编写解析器生成器时,我将 | 用作表示备选项(和 & 用于表示序列)。 - Kyle
1
我认为,如果你正在寻找一个指导方针,那么就是:如果你期望用户想要形成复杂的表达式,并且有一个已经被广泛接受的符号表示这些表达式,那么重载运算符可能是合适的。 - Kyle
显示剩余3条评论
2个回答

4
这是我找到的最接近运算符重载指南的东西: MSDN运算符重载 我从C++背景转到C#,在C++中,运算符重载是规范的一部分。但C#的问题在于所有对象都是引用类型。由于这个原因,你不能重载 = 运算符。然而,编写扩展方法可以使用相同的代码实现相同的目的。
正如评论中所说,我也在C#中工作了将近10年,但从未见过有人重载运算符。

+1 同样的情况。正如评论中所指出的,我也已经在C#上工作了将近10年,但还没有看到有人重载运算符。 - Jaydeep Karena
1
@jaydeepkarena System.Numerics命名空间中的BigInteger类使用运算符重载,以便您可以将BigInteger实例与Int32、UInt32和其他整数结构混合使用二进制算术运算符。在Java中,您没有运算符重载,因此您必须使用BigInteger和BigDecimal类的add()、divide()等成员来获得相同的结果。此外,我遇到了整数非引用类型的问题,因此我创建了自己的ManagedIntegral类,包装了未管理的整数,这些类广泛使用运算符重载。 - Patrik Nusszer

2

我想使用运算符重载的情况是C#不允许其在扩展方法中使用。重载TimeSpan的operator/和operator*肯定很好,但你不能有扩展运算符。

否则,我认为只有在创建代数类型或(也许)使用链接运算符的新小语言时才有意义(类似于C++输出运算符)。例如,我可以看到围绕运算符的Linq变体很有趣。


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