System.String 仅重载了两个运算符
public static bool operator ==(string a, string b)
{
return string.Equals(a, b);
}
public static bool operator !=(string a, string b)
{
return !string.Equals(a, b);
}
但是当使用 += 进行字符串连接时,示例:
private static void Main()
{
String str = "Hello ";
str += "World";
Console.WriteLine(str);
}
效果很好,
那么,如果 System.String 没有重载运算符 += 它如何连接字符串呢?
首先,运算符
+=
不能重载。如果你有表达式 A += B
,它的编译就像你写的:*
A = A + B
好吧,这就是为什么
string
不会重载operator +=
(因为它不能重载)。那么,为什么它也不会超载operator +
呢?这只是 CLR 和 C# 之间的又一区别。 C# 编译器知道像 string
和 int
这样的类型是特殊的,并且它会为其运算符生成特殊代码(对于 string.Concat()
调用 string
,对于 add
调用 int
指令)。
为什么这些操作员会受到特殊对待?因为您希望他们受到特殊的对待。我认为这对于
int
来说是最清楚的:
int
添加都被编译为方法调用,这会增加大量开销。因此,使用了 int
加法的特殊指令。checked
和 unchecked
运算符。如果编译器只有 operator +
应该如何处理? (它实际上的作用是使用指令 add
来表示未检查的溢出,使用 add.ovf
来检查溢出。)并且出于性能原因,您也希望以特殊方式处理
string
加法。例如,如果您有 string
s a
、b
和 c
并编写 a + b + c
,然后将其编译为对 operator +
的两次调用,则需要为string
的结果,效率很低。相反,编译器会将该代码生成为 a + b
,它只能直接分配所需长度的一个字符串。* 这并不完全正确,有关详细信息,请参阅 C# 规范中 Eric Lippert 的文章
复合赋值,第一部分 和 复合赋值。另请注意缺少的分号,string.Concat(a, b, c)
确实是一个表达式,例如,您可以写
A += B
。string.Concat
没有显式实现,但它可以工作,因为编译器确实有魔力
+=
str += "World";
str = str + "World";
str = str.Concat("World");
相当于
string += otherString
这个 .NET 链接提到了串联运算符,这个 .NET 链接讨论了两个操作之间的关系。