C# 中的重载运算符实际上是一种好习惯吗? [关闭]

Posted

技术标签:

【中文标题】C# 中的重载运算符实际上是一种好习惯吗? [关闭]【英文标题】:Is overloading operators in C# actually good practice? [closed] 【发布时间】:2017-09-18 19:43:03 【问题描述】:

作为 C# 的新手,我知道运算符重载的目的和用途,并且我可以看到它有时在非常特殊的情况下是多么优雅,例如否定一个值对象以一次否定它的所有字段,但是这样的事情总是可以用简单的说话方法来完成。是否有一些标准可以用作指导,何时或是否重载运算符或何时简单地使用方法?我找不到类似的东西,所以这只是品味/编程范式/风格的问题吗?

【问题讨论】:

我从未听说过任何描述如何在运算符和方法之间进行选择的指南。但是在使用 C# 和 .Net 几年后,我很少看到运算符重载(== 和 != 除外)。 如果我的问题的所有其他解决方案(我能想到的)都是荒谬的,我当然会这样做。永远不要说永远,但是在十年的专业编写 C# 中,我不记得有这样的案例。 我认为这主要是个人喜好。我们的 C# 代码库有一些核心几何类型(向量、点、方向),这些几何类型具有重载运算符以支持交叉/点积、转换等。我认为像这样的基本数据类型是有意义的,但在大多数情况下会避免它. 如果您正在编写算术原语(如有理数、复数或向量/矩阵类型),强制用户使用静态方法来描述简单的转换很快就会变得笨拙。 p0 = r * u - Axis + origin;p0 = Point.Add( Vector.Subtract( Vector.Multiply( r, u ), Axis ), origin ); 更具可读性。我唯一一次在代数上下文之外使用运算符重载是在编写解析器生成器时,我重载了| 来表示替代方案(并重载& 来表示序列)。 我想说,如果你正在寻找一个指导方针,那就是:如果你希望用户想要形成复杂的表达式并且这些表达式有一个完善的表示法,那么重载运算符可能是合适的. 【参考方案1】:

这是我发现的最接近任何类型的运算符重载指南的东西: MSDN operator overload

我从 C++ 背景来到 C#,其中运算符重载是规范的一部分。 C# 的不足之处在于所有对象都是引用。因此,您不能重载 = 运算符,在我看来,这将是重载复杂对象的最有用的运算符。话虽如此,编写扩展方法可以用相同的代码实现相同的目标。

正如 cmets 中所指出的,我也在 C# 中工作了近 10 年,还没有看到有人重载运算符。

【讨论】:

+1 相同And as noted in the comments, I have also been working in C# for nearly 10 years and have yet to see someone overload an operator @jaydeepkarena System.Numerics 命名空间中的 BigInteger 类使用运算符重载,因此您可以将 BigInteger 实例与 Int32、UInt32 和其他整数结构与二进制算术运算符混合使用。在 Java 中,您没有运算符重载,因此您求助于使用 add()、divide() 等... BigInteger 和 BigDecimal 类的成员以获得相同的结果。此外,我在积分是非引用类型时遇到了问题,所以我制作了自己的 ManagedIntegral 类来包装未管理的积分,这些积分广泛使用了运算符重载。【参考方案2】:

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

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

【讨论】:

以上是关于C# 中的重载运算符实际上是一种好习惯吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从循环内部返回是一种好习惯[关闭]

通过 :: 调用包中的函数是一种好习惯吗

将 Optional 用作类中的属性是一种好习惯吗? [复制]

使用表单属性并将输入元素放在 HTML 中的表单标记之外是一种好习惯吗?

在数据仓库(关系)中有外键是一种好习惯吗?

为啥捕获 RuntimeException 不被认为是一种好的编程习惯? [关闭]