2009-11-19 1 views
9

Выполняет ли C# оптимизацию времени компиляции для постоянной конкатенации строк? Если да, то как должен мой код писать, чтобы воспользоваться этим?C# Compal-Time Concatenation для констант String

Пример: как они сравниваются во время выполнения?

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

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

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

ответ

15

Да, это так. Вы можете проверить это, используя ildasm или Reflector для проверки кода.

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

переводится на

.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 

Существует что-то еще более интересное, но рассказал, что происходит. Если у вас есть строковый литерал в сборке, CLR создаст только один объект для всех экземпляров того же литерала в сборке.

Таким образом:

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

напечатает "True" на консоли! Эта оптимизация называется string interning.

6

В соответствии с Reflector:

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

даже в конфигурации отладки.