为什么运算符重载没有更频繁地使用?
在许多场景中,运算符重载可以让您更好地表达自己。为什么它们在 C# 中很少使用?
In many scenarios, operator overloads allow you to express yourself better. Why are they hardly used in C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
它们不经常使用,因为对大多数类别的对象进行数学运算(大多数运算符都是如此)通常没有意义。您想要的操作的语义通常在某些方面有所不同。例如,当您实际需要聚合或分组时,您不会对一堆 OrderLine 对象使用加法。
要使用您现在在问题注释中提供的示例,“+”似乎是将子元素放入父元素的不错方法,但操作具有完全不同的语义。 “+”表明您将以数学方式将它们加在一起,而实际上您的目标是在两者之间建立层次结构关系。这对你来说可能有意义,但我想在第一次阅读时,对于很多程序员来说可能并不明显。
它们很少被使用,因为它们很少适合。
They are not used very frequently because often it doesn't make sense to have mathematical operations (which the majority of operators are) over most classes of objects. The semantics of the operations you want are usually different in some way. You wouldn't use addition against a bunch of OrderLine objects, for example, when you actually want aggregation or grouping.
To use the example that you have now provided in the comments for your question, "+" may seem like a decent way to put child elements into a parent element but the operations have entirely different semantics. "+" suggests that you would be adding them together mathematically, when in fact you are aiming for a hierarchial relationship between the two. It may make sense to you, but I imagine that on first read it is probably not obvious to a lot of programmers.
They're rarely used because they rarely fit.
它们稀有的另一个原因是,虽然函数重载可以通过函数名称并且经常通过上下文进行自我记录,但运算符通常只有一两个字符长。
因此,无法明确说明重载的确切目的是什么。例如,字符串 != 比较运算符重载中没有空间来说明它是比较长度、逐个字符进行不区分大小写的比较,还是在静态索引数组中查找值并比较它们(尽管这是一个可笑的例子)。
Another reason for their rarity is that while function overloading can be made self documenting, via the name of the function, and quite often by context, an operator is generally only one or two characters long.
Because of this, it can't be made explicitly clear what the overload is precisely intended to achieve. For example a string != comparison operator overload has no space within it to say whether it is comparing length, doing a character by character case insensitive comparison, or looking up the values in a static indexed array, and comparing them (although this is a ludicrous example).
来自http://msdn.microsoft.com/en-us/library/a1sway8w。 aspx:
用户定义的类型可以重载<<运算符(请参阅运算符); 第一个操作数的类型必须是用户定义的类型,第二个操作数的类型必须是 int。当二元运算符重载时,相应的赋值运算符(如果有)也会隐式重载。
From http://msdn.microsoft.com/en-us/library/a1sway8w.aspx:
User-defined types can overload the << operator (see operator); the type of the first operand must be the user-defined type, and the type of the second operand must be int. When a binary operator is overloaded, the corresponding assignment operator, if any, is also implicitly overloaded.
我发现它们更多地用在易于实现 DSL(领域特定语言)的语言中。
一个很好的例子是 PEG,它使用 BNF 的闭合表示法:在这里,使用运算符是非常自然和富有表现力的。
我认为 Lua 的 Lpeg 库和 Nimrod 的 PEG 模块都使用了此功能。
I see them used more in languages making easy to do DSLs (domain specific languages).
A good example is PEG, which uses notation close of BNF: here, using operators is quite natural and expressive.
Lpeg library for Lua and Nimrod's PEG module are both using this capability, among others I suppose.
.Net 中运算符重载的另一个大问题是您无法重载所有运算符。因此,例如运算符
<<
或>>
不可用。还有一些在某些频繁使用的 C++ 类中无法重载的内容。因此,在大多数情况下,这是没有意义的,因为不幸的是您无法访问所有操作员。
Another big issue about operator overloading in .Net is that you're not able to overload all operators. So e.g. the operators
<<
or>>
are note available. And also a few more which are in some C++ classes heavily used are not able to be overloaded.So in most scenarios it doesn't make sense, cause you don't have access to all operators unfortunately.