Например, знает ли компилятор для перевода
string s = "test " + "this " + "function";
к
string s = "test this function";
и, таким образом, избежать удара производительности с помощью конкатенации строк?
Например, знает ли компилятор для перевода
string s = "test " + "this " + "function";
к
string s = "test this function";
и, таким образом, избежать удара производительности с помощью конкатенации строк?
Да. Это гарантируется спецификацией С#. Это в разделе 7.18 (спецификации С# 3.0):
Всякий раз, когда выражение выполняет требования, перечисленные выше, выражение оценивается в время компиляции. Это справедливо, даже если выражение является подвыражением более крупное выражение, содержащее непостоянные конструкции.
( "Требования, перечисленные выше" включают в себя оператор +, применяемый к двум константным выражениям.)
См. также этот вопрос.
Просто примечание к связанной теме - компилятор С# также будет "оптимизировать" несколько конкатенаций с использованием нелитералов с использованием оператора "+" для одного вызова многопараметрической перегрузки String.Concat().
So
string result = x + y + z;
компилируется в нечто эквивалентное
string result = String.Concat( x, y, z);
а не более наивная возможность:
string result = String.Concat( String.Concat( x, y), z);
Ничто не разрушило землю, но просто захотело добавить этот бит в обсуждение оптимизации конкатенации строк. Я не знаю, соответствует ли это поведение стандарту языка или нет.
Да.
С# не только оптимизирует конкатенацию строковых литералов, но и сводит эквивалентные строковые литералы в константы и использует указатели для ссылки на все ссылки на одну и ту же константу.
Да. Вы можете явно это увидеть с помощью ILDASM.
Пример:
Здесь программа, похожая на ваш пример, за которой следует скомпилированный код CIL:
Примечание. Я использую функцию String.Concat(), чтобы увидеть, как компилятор рассматривает два разных метода конкатенации.
Программа
class Program
{
    static void Main(string[] args)
    {
        string s = "test " + "this " + "function";
        string ss = String.Concat("test", "this", "function");
    }
}
ILDASM
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       29 (0x1d)
  .maxstack  3
  .locals init (string V_0,
           string V_1)
  IL_0000:  nop
  IL_0001:  ldstr      "test this function"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "test"
  IL_000c:  ldstr      "this"
  IL_0011:  ldstr      "function"
  IL_0016:  call       string [mscorlib]System.String::Concat(string,
                                                              string,
                                                              string)
  IL_001b:  stloc.1
  IL_001c:  ret
} // end of method Program::Main
Обратите внимание, что в IL_0001 компилятор создал константу "проверить эту функцию" в отличие от того, как компилятор рассматривает функцию String.Concat(), которая создает константу для каждого из параметров .Concat(), а затем вызывает. Функция Concat().
Из уст лошадей:
Конкатенация - это процесс добавления одной строки в конец другой строки. Когда вы объединяете строковые литералы или строковые константы с помощью оператора +, компилятор создает одну строку. Не происходит конкатенации времени выполнения. Однако строковые переменные могут быть объединены только во время выполнения. В этом случае вы должны понимать последствия работы различных подходов.
Я считаю, что ответ на этот вопрос - да, но вам нужно будет посмотреть, что компилятор выплевывает... просто компилируйте и используйте рефлектор на нем: -)
У меня был аналогичный вопрос, но о VB.NET вместо С#. Самый простой способ проверить это - просмотреть скомпилированную сборку в Reflector.
Ответ заключался в том, что компилятор С# и VB.NET оптимизирует конкатенацию строковых литералов.