对于StringBuilder类,为什么不重载+=运算符,而是使用独特的.Append()方法呢?
.Append()方法只能将字符串连接起来,那么为什么他们不直接重载+=运算符呢:
StringBuilder sb = new StringBuilder();
sb += "My string";
这是效率的问题吗? 还是传统或直觉的问题?
谢谢,
对于StringBuilder类,为什么不重载+=运算符,而是使用独特的.Append()方法呢?
.Append()方法只能将字符串连接起来,那么为什么他们不直接重载+=运算符呢:
StringBuilder sb = new StringBuilder();
sb += "My string";
这是效率的问题吗? 还是传统或直觉的问题?
谢谢,
算术运算应仅限于行为类似于算术值的类型。两个字符串的总和就已经够糟糕的了,将加法操作与字符串串联混淆是一个有问题的选择,因为字符串串联遵守的规则很少; 特别是,a + b != b + a
。
但是对于 可变状态 而不是 算数值 定义的字符串 构建器,这种混淆实在太糟糕了。 两个东西的总和应该是第三个与两个加数不同的东西。也就是说,a += b
必须 与 a = a + b
具有相同语义,而不是 a.MutateWith(b)
。如果最后没有对 a
进行赋值,则复合赋值运算符就是错误的运算符。
更一般地说:永远不要做可爱的运算符重载。运算符重载是为了使两个复杂的数字相加得到第三个数字,而不是为了让一个客户加上一罐花生酱等于购买订单或其他愚蠢的事情。
a += b
实际上会将一个新的组合委托分配给 a。我承认这并不理想,但至少它遵循了 Eric 设定的最大规则。 - dlev+
被选择表示字符串的连接一样令人遗憾,同样不幸的是+
在委托中表示顺序组合。但是,就像字符串一样,两个委托可以相加得到第三个。当您在委托上使用+=
时,它确实具有a = a + b
的语义。但我从来没有喜欢过C#的这个特性,它对我来说似乎太过可爱了。 - Eric LippertComplex * double
用户定义运算符,只需将实部和虚部乘以double即可;这是两个乘法。如果没有这个,我们必须先通过调用转换器来创建Complex
(1.5 + 0i),然后执行通常的四个乘法和两个加法来将两个复数相乘。通过拥有一个特殊目的的用户定义运算符,在这种常见情况下,我们可以节省一半以上的工作。 - Eric Lippert
List
没有+=来添加一个对象... - Shahar