Вопрос

I know how the following code be evaluated:

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

It basically do 3 evaluation (please correct me if wrong):

  1. Assign a string "Hello" to variable s
  2. Create another string "Hello My " and assign to variable s
  3. Create another string "Hello My World" and assign to variable s

Which basically leaving "Hello" and "Hello My " weakly referenced and can be GC-ed.

What I don't know, how they evaluate the following code?

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

Does it evaluate the same?

Update

The answer give me another question. How about the following code?

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

where

private string EvaluateJoin(){ return " My "; }
Это было полезно?

Решение

To the first bit, "yes, basically", up to

Which basically leaving "Hello" and "Hello My " weakly referenced and can be GC-ed.

No, they aren't referenced at all any more.

Edit: Henk correctly notes that "Hello" and " My ", however, are interned (due to ldstr) - so will not be collected. The combined "Hello My ", however, is not interned and will be collectable.

For the second example: because those are all constants in a single expression, the compiler combines the constant at compile time; that represents a single interned string "Hello My World", which you can see in the IL.

For example:

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

    s = "Hello" + " My " + " World";
    System.Console.WriteLine(s);
}

compiles to:

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

Here you can clearly see both the Concats for the first example, and the single pre-combined string for the second.

Другие советы

Which basically leaving "Hello" and "Hello My " weakly referenced and can be GC-ed.

No, strings are interned and constant strings will never be GC-ed. So only "Hello My " is collectable.

Does it evaluate the same?

The end result certainly is the same. There are no evaluation issues (timing, dependencies) here.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top