Sorprendentemente, depende.
Si haces esto en un método:
void Foo() {
String one = "1";
String two = "2";
String result = one + two + "34";
Console.Out.WriteLine(result);
}
entonces el compilador parece emitir el código usando String.Concat
como respondió @Joachim (+1 a él por cierto).
Si los define como constantes , por ejemplo:
const String one = "1";
const String two = "2";
const String result = one + two + "34";
o como literales , como en la pregunta original:
String result = "1" + "2" + "3" + "4";
entonces el compilador optimizará esos +
signos. Es equivalente a:
const String result = "1234";
Además, el compilador eliminará expresiones constantes extrañas y solo las emitirá si se usan o se exponen. Por ejemplo, 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);
}
Solo genera una cadena, la constante result
(igual a "1234"). one
y two
no aparecen en el IL resultante.
Tenga en cuenta que puede haber más optimizaciones en tiempo de ejecución. Solo me guío por lo que IL se produce.
Finalmente, en lo que respecta al internado, se internan constantes y literales, pero el valor que se interpone es el valor constante resultante en el IL, no el literal. Esto significa que puede obtener incluso menos objetos de cadena de los que espera, ya que múltiples constantes o literales idénticamente definidos serán en realidad el mismo objeto. Esto se ilustra con lo siguiente:
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();
}
}
En el caso de que las cadenas se concatenan en un bucle (o de otro modo de forma dinámica), se termina con una cadena adicional por concatenación. Por ejemplo, lo siguiente crea 12 instancias de cadena: 2 constantes + 10 iteraciones, cada una de las cuales da como resultado una nueva instancia de cadena:
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a";
Console.ReadKey();
}
}
Pero (también sorprendentemente), el compilador combina múltiples concatenaciones consecutivas en una sola concatenación de múltiples cadenas. Por ejemplo, este programa también solo produce 12 instancias de cadena. Esto se debe a que " Incluso si utiliza varios operadores + en una declaración, el contenido de la cadena se copia solo una vez " .
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a" + result;
Console.ReadKey();
}
}