c# - System.String 不会重载运算符 += 但字符串连接有效,如何?

标签 c# .net string compiler-construction clr

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 指令)。

为什么这些运算符(operator)会受到特殊对待?因为您希望以特殊方式对待他们。我认为这对于 int 是最清楚的:

  1. 你不想要每个 int另外要编译为方法调用,那会增加很多开销。因此,特别说明 int使用了加法。
  2. 整数加法在溢出方面的表现并不总是相同。有一个编译器开关可以抛出溢出异常,您也可以使用 checkedunchecked运营商。如果编译器只有 operator +,它应该如何处理它? ? (它实际上所做的是使用指令 add 来处理未经检查的溢出,使用 add.ovf 来处理已检查的溢出。)

而你想治疗string出于性能原因,也以特殊方式添加。例如,如果您有 string s a , bc然后写a + b + c然后将其编译为对 operator + 的两次调用, 你需要分配一个临时的 string对于 a + b 的结果,这是低效的。相反,编译器将该代码生成为 string.Concat(a, b, c) , 可以直接只分配一个所需长度的字符串。


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

关于c# - System.String 不会重载运算符 += 但字符串连接有效,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14473651/

相关文章:

c# - VB.NET SQL Server 查询到 LINQ

c# - COMException (0x80040154) : Class not registered when using AxAcroPDFLib

python - 字符串搜索库的结果 - 错误或功能或我的编码错误?

c# - 在 ASP.NET 部署中包含 bin 子文件夹

c# - ArrayList 与 C# 中的 List<>

java - 如何在java中替换xml文件中的字符串而不将文件内容加载到内存中?

c - 在 C 中创建一个 char[] 数组

c# - 未应用 MVC AddJsonOptions ReferenceLoopHandling 配置

c# - 如何在不锁定 GUI 的情况下将数千个项目添加到绑定(bind)集合

c# - 如何修复 : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical?