这个字符串连接是如何评估的?

Fen*_*ndy 1 c# string immutability

我知道如何评估以下代码:

string s = "Hello";
s += " My ";
s += " World";
Run Code Online (Sandbox Code Playgroud)

它基本上做3评价(如果错误请纠正我):

  1. 为变量s分配字符串"Hello"
  2. 创建另一个字符串"Hello My"并分配给变量s
  3. 创建另一个字符串"Hello My World"并分配给变量s

这基本上是离开"Hello""Hello My "弱引用,可以是GC编辑.

我不知道,他们如何评估以下代码?

string s = "Hello" + " My " + " World";

它评价相同吗?

更新

答案给了我另一个问题.以下代码怎么样?

string s = "Hello" + EvaluateJoin() + " World";

哪里

private string EvaluateJoin(){ return " My "; }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 8

到第一位,"是的,基本上",最多

这基本上留下了"Hello"和"Hello My"弱引用,可以进行GC编辑.

不,他们没有被引用的所有了.

编辑:Henk正确地注意到"Hello"并且" My ",然而,被拘禁(由于ldstr) - 所以不会被收集."Hello My "但是,合并后的内容并非实际可收回.

对于第二个例子:因为这些都是单个表达式中的常量,编译器在编译时组合常量; 表示单个实习字符串"Hello My World",您可以在IL中看到.

例如:

static void Main()
{
    string s = "Hello";
    s += " My ";
    s += " World";
    System.Console.WriteLine(s);

    s = "Hello" + " My " + " World";
    System.Console.WriteLine(s);
}
Run Code Online (Sandbox Code Playgroud)

编译为:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: ldstr "Hello"
    L_0005: ldstr " My "
    L_000a: call string [mscorlib]System.String::Concat(string, string)
    L_000f: ldstr " World"
    L_0014: call string [mscorlib]System.String::Concat(string, string)
    L_0019: call void [mscorlib]System.Console::WriteLine(string)
    L_001e: ldstr "Hello My  World"
    L_0023: call void [mscorlib]System.Console::WriteLine(string)
    L_0028: ret 
}
Run Code Online (Sandbox Code Playgroud)

在这里,您可以清楚地看到Concat第一个示例的s和第二个示例的单个预组合字符串.