5

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 没有重载运算符 += 它连接字符串怎么办?

4

4 回答 4

8

首先,运算符+=不能重载。如果你有表达式A += B,它的编译就像你写的一样:*

A = A + B

好的,这就是为什么string不重载operator +=(因为它不能重载)。那么,为什么它也不超载operator +呢?这只是 CLR 和 C# 之间的另一个区别。C# 编译器知道类型喜欢stringint是特殊的,它会为它们的运算符生成特殊代码(调用string.Concat()forstringaddfor 的指令int)。

为什么要对这些运算符进行特殊处理?因为你希望他们以特殊的方式对待。我认为这是最清楚的int

  1. 您不希望每个int添加都被编译为方法调用,这会增加很多开销。因此,使用了特殊的int加法指令。
  2. 整数加法在溢出方面的表现并不总是相同。有一个编译器开关可以抛出溢出异常,您也可以使用checkedandunchecked运算符。如果它只有 编译器应该如何处理operator +?(它实际上所做的是将指令add用于未检查的溢出和add.ovf检查的溢出。)

出于性能原因,您还想以string特殊方式处理加法。例如,如果你有stringsa和writeb然后你把它编译为对 的两次调用,你需要为 的结果分配一个临时的,这是低效的。相反,编译器将该代码生成为,它只能直接分配一个所需长度的字符串。ca + b + coperator +stringa + bstring.Concat(a, b, c)


* 这并不完全正确,详情请参阅 Eric Lippert 的文章Compound Assignment, Part One and Compound assignment在 C# 规范中。还要注意缺少的分号,A += B真的是一个表达式,例如,你可以写X += Y += Z;.

于 2013-01-23T10:53:08.653 回答
5

运算符没有重载+=,它是. 字符串也是如此。var = var + newValue

+= 运算符(C# 参考)

+= 运算符不能直接重载,但用户定义的类型可以重载 + 运算符

考虑以下示例:

string str = "new string";
str += "new value";

这等于:

str = str + "new value";

string.Concat在编译时内部调用。

于 2013-01-23T06:26:46.227 回答
3

+=没有显式实现,但它可以工作,因为编译器做到了它的魔力

str += "World";

str =  str + "World";

str = str.Concat("World");
于 2013-01-23T06:26:55.780 回答
0

正如上面的人所说,根据.NET,string += otherString相当于

string = string + otherString

这个 .NET 链接提到了连接运算符,这个 .NET 链接讨论了这两个操作之间的关系。

于 2013-01-23T06:34:21.227 回答