Sorprendentemente, depende.
Si hace 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 @Joachim respondió (1 a él por cierto).
Si los definen como constantes de, por ejemplo:
const String one = "1";
const String two = "2";
const String result = one + two + "34";
o como literales, al igual que en la pregunta original:
String result = "1" + "2" + "3" + "4";
entonces el compilador optimizará lejos esos +
signos . Es equivalente a:
const String result = "1234";
Por otra parte, el compilador eliminación de expresiones constantes extraños, y sólo emiten ellos si se utilizan 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);
}
sólo genera una String la constante de result
(igual a "1234"). one
y two
no se muestran en la IL resultante.
Tenga en cuenta que puede haber más optimizaciones en el tiempo de ejecución. Solo voy por lo que se produce IL.
Finalmente, en lo que respecta al internamiento, las constantes y los literales son internados, pero el valor que se interna 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 definidos de forma idéntica serán en realidad el mismo objeto! Esto se ilustra por el 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 en que cadenas se concatenan en un bucle (o de otra forma dinámica), que terminan con una cadena extra por concatenación.Por ejemplo, la siguiente crea 12 instancias de cadena: 2 constantes + 10 iteraciones, cada uno que resulta en una nueva instancia de la secuencia:
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), múltiples concatenaciones consecutivos se combinan por el compilador en una sola multi- concatenación de cadenas Por ejemplo, este programa también solo produce 12 instancias de cadena. Esto se debe a que "Even if you use several + operators in one statement, the string content is copied only once."
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a" + result;
Console.ReadKey();
}
}
Cuerdas sólo son internados si se llama explícitamente String.Intern. –
@JoeWhite: ¿verdad? –
No del todo. Todos los literales de cadena son internados automáticamente. Los resultados de las operaciones de cadena no lo son. –