为什么无法在C#中重载复合赋值运算符?


11

标题具有误导性,因此请阅读整个问题:-)

所谓“复合赋值操作符”我心里有这样的结构op=,例如+=。纯赋值运算符(=)不属于我的问题。

“为什么”我不是指观点,而是某些设计师或其同事等表达其推理(即设计选择的来源)时的资源(书,文章等)。

我对C ++和C#中的不对称感到困惑(是的,我知道C#不是C ++ 2.0)-在C ++中,您将重载运算符+=,然后几乎完全+依靠先前定义的运算符自动编写适当的运算符。在C#中是相反的-您过载++=为您综合了。

如果我没记错的话,后面的方法在使用real时会失去优化的机会+=,因为必须创建新的对象。因此,这种方法必须具有很大的优势,但是MSDN却不愿透露任何信息。

我想知道这样做的好处是什么,因此,如果您在C#书籍,技术讲座视频,博客文章中发现了解释,我将不胜感激。

我发现最接近的是Eric Lippert博客上的评论为什么C#中重载运算符总是静态的?汤姆·布朗(Tom Brown)。如果首先确定了静态重载,则它仅指示可以为结构重载哪些运算符。这进一步指示了可以为类重载的内容。


3
您是否有新的C ++样式的链接?天真的,+=首先过载似乎是荒谬的。为什么要使组合操作而不是部分操作过载?
泰拉斯汀

1
我相信这些术语是“复合赋值运算符”。
Ixrec

2
@greenoldman Telastyn可能暗示用+来实现+ =似乎比其他方式更自然,因为从语义上讲+ =是+和=的组合。据我所知,+调用+ =在很大程度上是一种优化技巧。
Ixrec

1
@Ixrec:有时,a + = b有意义,而a = a + b却不:考虑身份可能很重要,A不能重复,无论如何。有时,a = a + b有意义,而a + = b则没有:考虑不可变的字符串。因此,实际上需要一种能力来决定分别使哪个过载。当然,如果所有必要的构建块都存在并且没有明确禁用,则自动生成丢失的块是个好主意。不是说C#允许那个atm,即afaik。
Deduplicator 2015年

4
@greenoldman-我了解这种动机,但就个人而言,我发现*=对引用类型进行变异在语义上是不正确的。
Telastyn

Answers:


12

我找不到为此的参考,但是我的理解是C#团队希望提供一个合理的运算符重载子集。当时,操作员超载的说唱不好。人们断言,它使代码模糊不清,只能用于邪恶。在设计C#时,Java向我们展示了没有运算符重载会令人讨厌。

因此,C#希望平衡运算符的重载,以使做恶事更加困难,但您也可以做得很好。改变赋值的语义是被认为总是邪恶的事情之一。通过允许+=其亲属过载,它将允许这种事情。例如,如果+=更改引用而不是创建新引用,则它不会遵循预期的语义,从而导致错误。


谢谢,如果您不介意,我将把这个问题再延长一点,如果没有人以实际设计的理由击败您,我将接受您的意见以结束它。再次-谢谢。
greenoldman

@greenoldman-同样应该。我也希望有人能给出更具体的参考答案。
Telastyn

那么,在这个地方不可能同时舒适地,毫不含糊地谈论指针和指尖了吗?该死的耻辱。
Deduplicator 2015年

“人们断言它混淆了代码”-尽管这仍然是事实,您是否看到过某些F#库?操作员噪音。如quanttec.com/fparsec
书斋
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.