Surpreendentemente, depende.
Se você fizer isso em um método:
void Foo() {
String one = "1";
String two = "2";
String result = one + two + "34";
Console.Out.WriteLine(result);
}
então o compilador parece emitir o código usando String.Concat
como @Joachim respondeu (+1 para ele aliás).
Se você os definir como constantes , por exemplo:
const String one = "1";
const String two = "2";
const String result = one + two + "34";
ou como literais , como na pergunta original:
String result = "1" + "2" + "3" + "4";
então o compilador irá otimizar esses +
sinais. É equivalente a:
const String result = "1234";
Além disso, o compilador removerá expressões constantes estranhas e apenas as emitirá se forem usadas ou expostas. Por exemplo, este programa:
const String one = "1";
const String two = "1";
const String result = one + two + "34";
public static void main(string[] args) {
Console.Out.WriteLine(result);
}
Gera apenas uma string - a constante result
(igual a "1234"). one
e two
não aparecem no IL resultante.
Lembre-se de que pode haver mais otimizações no tempo de execução. Estou apenas analisando o que o IL é produzido.
Finalmente, no que diz respeito ao internamento, constantes e literais são internados, mas o valor que é internado é o valor da constante resultante no IL, não o literal. Isso significa que você pode obter ainda menos objetos de string do que o esperado, já que várias constantes ou literais definidas de forma idêntica serão na verdade o mesmo objeto! Isso é ilustrado pelo seguinte:
public class Program
{
private const String one = "1";
private const String two = "2";
private const String RESULT = one + two + "34";
static String MakeIt()
{
return "1" + "2" + "3" + "4";
}
static void Main(string[] args)
{
string result = "1" + "2" + "34";
// Prints "True"
Console.Out.WriteLine(Object.ReferenceEquals(result, MakeIt()));
// Prints "True" also
Console.Out.WriteLine(Object.ReferenceEquals(result, RESULT));
Console.ReadKey();
}
}
No caso em que Strings são concatenadas em um loop (ou de outra forma dinamicamente), você acaba com uma string extra por concatenação. Por exemplo, o seguinte cria 12 instâncias de string: 2 constantes + 10 iterações, cada uma resultando em uma nova instância de String:
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a";
Console.ReadKey();
}
}
Mas (também surpreendentemente), várias concatenações consecutivas são combinadas pelo compilador em uma única concatenação multi-string. Por exemplo, este programa também produz apenas 12 instâncias de string! Isso ocorre porque " Mesmo se você usar vários operadores + em uma instrução, o conteúdo da string é copiado apenas uma vez. "
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a" + result;
Console.ReadKey();
}
}