2009-11-19 14 views
9

Führt C# eine Kompilierzeitoptimierung für konstante Stringverkettung durch? Wenn ja, wie muss mein Code geschrieben werden, um das auszunutzen?C# Kompilierzeitverkettung für Stringkonstanten

Beispiel: Wie werden diese zur Laufzeit verglichen?

Console.WriteLine("ABC" + "DEF"); 

const string s1 = "ABC"; 
Console.WriteLine(s1 + "DEF"); 

const string s1 = "ABC"; 
const string s2 = s1 + "DEF"; 
Console.WriteLine(s2); 

Antwort

15

Ja, tut es. Sie können dies überprüfen, indem Sie ildasm oder Reflector verwenden, um den Code zu überprüfen.

static void Main(string[] args) { 
    string s = "A" + "B"; 
    Console.WriteLine(s); 
} 

wird

übersetzt
.method private hidebysig static void Main(string[] args) cil managed { 
    .entrypoint 
    // Code size  17 (0x11) 
    .maxstack 1 
    .locals init ([0] string s) 
    IL_0000: nop 
    IL_0001: ldstr  "AB" // note that "A" + "B" is concatenated to "AB" 
    IL_0006: stloc.0 
    IL_0007: ldloc.0 
    IL_0008: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_000d: nop 
    IL_000e: br.s  IL_0010 
    IL_0010: ret 
} // end of method Program::Main 

Es gibt etwas noch interessanter, aber miteinander verbundene, dass passiert. Wenn Sie in einer Assembly ein Zeichenfolgenliteral verwenden, erstellt die CLR nur ein Objekt für alle Instanzen desselben Literals in der Assembly. So

:

static void Main(string[] args) { 
    string s = "A" + "B"; 
    string t = "A" + "B"; 
    Console.WriteLine(Object.ReferenceEquals(s, t)); // prints true! 
} 

wird "True" auf der Konsole aus! Diese Optimierung wird string interning genannt.

6

Nach Reflector:

Console.WriteLine("ABCDEF"); 
Console.WriteLine("ABCDEF"); 
Console.WriteLine("ABCDEF"); 

auch in einer Debug-Konfiguration.