How many String objects will be created when using a plus sign in the below code?
String result = \"1\" + \"2\" + \"3\" + \"4\";
If it was
Chris Shain's answer is very good. As the person who wrote the string concatenation optimizer I would just add two additional interesting points.
The first is that the concatenation optimizer essentially ignores both parentheses and left associativity when it can do so safely. Suppose you have a method M() that returns a string. If you say:
string s = M() + "A" + "B";
then the compiler reasons that the addition operator is left associative, and therefore this is the same as:
string s = ((M() + "A") + "B");
But this:
string s = "C" + "D" + M();
is the same as
string s = (("C" + "D") + M());
so that is the concatenation of the constant string "CD" with M().
In fact, the concatenation optimizer realizes that string concatenation is associative, and generates String.Concat(M(), "AB") for the first example, even though that violates left associativity.
You can even do this:
string s = (M() + "E") + ("F" + M()));
and we'll still generate String.Concat(M(), "EF", M()).
The second interesting point is that null and empty strings are optimized away. So if you do this:
string s = (M() + "") + (null + M());
you'll get String.Concat(M(), M())
An interesting question then is raised: what about this?
string s = M() + null;
We cannot optimize that down to
string s = M();
because M() might return null, but String.Concat(M(), null) would return an empty string if M() returns null. So what we do is instead reduce
string s = M() + null;
to
string s = M() ?? "";
Thereby demonstrating that string concatenation need not actually call String.Concat at all.
For further reading on this subject, see
Why is String.Concat not optimized to StringBuilder.Append?