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

时间:2014-04-30 08:41:32

标签: c# string immutability

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

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

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

  1. 分配一个字符串" Hello"到变量s
  2. 创建另一个字符串" Hello My"并分配给变量s
  3. 创建另一个字符串" Hello My World"并分配给变量s
  4. 这基本上是"Hello""Hello My "弱引用,可以进行GC编辑。

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

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

    它的评价是否相同?

    更新

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

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

    ,其中

    private string EvaluateJoin(){ return " My "; }
    

2 个答案:

答案 0 :(得分: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);
}

汇编为:

.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 
}

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

答案 1 :(得分:2)

  

哪个基本上离开"你好"和#34;你好我的"弱引用,可以进行GC编辑。

不,字符串是固定的,常量字符串永远不会被GC编辑。所以只有"Hello My "可以收集。

  

它的评价是否相同?

最终结果肯定是一样的。这里没有评估问题(时间,依赖性)。