【发布时间】:2010-01-20 09:29:08
【问题描述】:
在许多情况下,运算符重载可以让您更好地表达自己。为什么它们在 C# 中很少使用?
【问题讨论】:
-
你能举几个例子让他们更有表现力吗?
-
突然想到:XmlDocument completeXml = 客户 + 订单; // 而不是创建 XmlDocument 并添加子元素。
在许多情况下,运算符重载可以让您更好地表达自己。为什么它们在 C# 中很少使用?
【问题讨论】:
它们的使用频率并不高,因为对大多数对象类别进行数学运算(大多数运算符都是如此)通常没有意义。您想要的操作的语义通常在某些方面是不同的。您不会对一堆 OrderLine 对象使用加法,例如,当您实际需要聚合或分组时。
要使用您现在在 cmets 中为您的问题提供的示例,“+”似乎是将子元素放入父元素的一种不错的方式,但操作具有完全不同的语义。 “+”表示您将以数学方式将它们加在一起,而实际上您的目标是两者之间的层次关系。这对您来说可能很有意义,但我想在第一次阅读时可能对很多程序员来说并不明显。
它们很少使用,因为它们很少适合。
【讨论】:
它们稀有的另一个原因是,虽然函数重载可以通过函数名和上下文进行自我记录,但运算符通常只有一两个字符长。
因此,无法明确明确重载的目的是什么。例如,字符串 != 比较运算符重载在其中没有空间来说明它是在比较长度、逐个字符进行不区分大小写的比较,还是在静态索引数组中查找值并比较它们(尽管这是一个可笑的例子)。
【讨论】:
来自http://msdn.microsoft.com/en-us/library/a1sway8w.aspx:
用户定义类型可以重载第一个操作数的类型必须是用户定义的类型,第二个操作数的类型必须是int。当二元运算符被重载时,相应的赋值运算符(如果有)也被隐式重载。
【讨论】:
我发现它们更多地用于使 DSL 变得容易的语言(特定领域的语言)。
一个很好的例子是PEG,它使用 BNF 的接近符号:在这里,使用运算符非常自然和富有表现力。
Lua 的 Lpeg 库和 Nimrod 的 PEG 模块都在使用这种功能,我猜想。
【讨论】:
.Net 中运算符重载的另一个大问题是您无法重载所有运算符。所以例如运算符<< 或>> 可用。还有一些在一些大量使用的 C++ 类中不能被重载。
所以在大多数情况下它没有意义,因为不幸的是您无法访问所有运算符。
【讨论】: