O dziwo, to zależy.
Jeśli zrobisz to metodą:
void Foo() {
String one = "1";
String two = "2";
String result = one + two + "34";
Console.Out.WriteLine(result);
}
wtedy kompilator wydaje się emitować kod używając String.Concat
odpowiedzi @Joachim (+1 do niego btw).
Jeśli zdefiniujesz je jako stałe , np .:
const String one = "1";
const String two = "2";
const String result = one + two + "34";
lub jako dosłowne , jak w pierwotnym pytaniu:
String result = "1" + "2" + "3" + "4";
wtedy kompilator zoptymalizuje te +
znaki. Jest to równoważne z:
const String result = "1234";
Ponadto kompilator usunie zbędne wyrażenia stałe i wyemituje je tylko wtedy, gdy są używane lub ujawniane. Na przykład ten program:
const String one = "1";
const String two = "1";
const String result = one + two + "34";
public static void main(string[] args) {
Console.Out.WriteLine(result);
}
Generuje tylko jeden ciąg - stałą result
(równą „1234”). one
i two
nie pojawiają się w wynikowym IL.
Pamiętaj, że w czasie wykonywania mogą pojawić się dalsze optymalizacje. Przechodzę tylko przez to, co zostało wyprodukowane przez IL.
Wreszcie, jeśli chodzi o internowanie, stałe i literały są internowane, ale wartość, która jest internowana, jest wynikową stałą wartością w IL, a nie literałem. Oznacza to, że możesz otrzymać nawet mniej obiektów łańcuchowych, niż się spodziewasz, ponieważ wiele identycznie zdefiniowanych stałych lub literałów będzie w rzeczywistości tym samym obiektem! Ilustrują to następujące elementy:
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();
}
}
W przypadku, gdy ciągi są łączone w pętli (lub w inny sposób dynamicznie), otrzymujesz jeden dodatkowy ciąg na konkatenację. Na przykład poniższy rysunek tworzy 12 instancji ciągu: 2 stałe + 10 iteracji, z których każda daje nową instancję ciągu:
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a";
Console.ReadKey();
}
}
Jednak (co jest również zaskakujące), kompilator łączy wiele kolejnych konkatenacji w jedną konkatenację z wieloma ciągami. Na przykład ten program również tworzy tylko 12 instancji łańcuchów! Dzieje się tak, ponieważ „ Nawet jeśli używasz kilku operatorów + w jednej instrukcji, treść ciągu jest kopiowana tylko raz ”.
public class Program
{
static void Main(string[] args)
{
string result = "";
for (int i = 0; i < 10; i++)
result += "a" + result;
Console.ReadKey();
}
}