Поскольку я не думаю, что ответы здесь охватывают все, я хотел бы сделать небольшое дополнение здесь.
Console.WriteLine(string format, params object[] pars)звонки string.Format. «+» Подразумевает конкатенацию строк. Я не думаю, что это всегда связано со стилем; Я склонен смешивать два стиля в зависимости от контекста, в котором я нахожусь.
Короткий ответ
Решение, с которым вы сталкиваетесь, связано с распределением строк. Я постараюсь сделать это просто.
Скажи, что у тебя есть
string s = a + "foo" + b;
Если вы выполните это, он будет оцениваться следующим образом:
string tmp1 = a;
string tmp2 = "foo"
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);
tmpздесь на самом деле не локальная переменная, но она временная для JIT (она помещается в стек IL). Если вы помещаете строку в стек (например, ldstrв IL для литералов), вы помещаете ссылку на указатель строки в стеке.
В тот момент, когда вы звоните concat эту ссылку, возникает проблема, потому что нет ни одной доступной строковой ссылки, содержащей обе строки. Это означает, что .NET необходимо выделить новый блок памяти, а затем заполнить его двумя строками. Причина, по которой это проблема, заключается в том, что распределение относительно дорого.
Что меняет вопрос на: Как вы можете уменьшить количество concatопераций?
Таким образом, грубый ответ: string.Formatдля> 1 конкатата '+' будет отлично работать для 1 конкатата. И если вы не заботитесь об оптимизации микропроцессора, string.Formatв общем случае все будет работать нормально.
Записка о культуре
А потом есть что-то под названием культура ...
string.Formatпозволяет использовать CultureInfoв вашем форматировании. Простой оператор «+» использует текущую культуру.
Это особенно важное замечание, если вы пишете форматы файлов и f.ex. doubleзначения, которые вы «добавляете» в строку. На разных машинах вы можете получить разные строки, если не используете string.Formatявные CultureInfo.
F.ex. подумайте, что произойдет, если вы измените «.» для ',' при написании файла значений, разделенных запятыми ... на голландском языке десятичный разделитель - запятая, так что ваш пользователь может просто получить «забавный» сюрприз.
Более подробный ответ
Если вы заранее не знаете точный размер строки, лучше использовать такую политику, чтобы перераспределить используемые вами буферы. Сначала свободное место заполняется, после чего данные копируются в.
Увеличение означает выделение нового блока памяти и копирование старых данных в новый буфер. Старый блок памяти может быть освобожден. Вы получаете практический результат: выращивание - дорогостоящая операция.
Наиболее практичный способ сделать это - использовать политику перераспределения. Наиболее распространенной политикой является перераспределение буферов со степенями 2. Конечно, вы должны сделать это немного умнее этого (поскольку нет смысла расти с 1,2,4,8, если вы уже знаете, что вам нужно 128 символов) ) но вы получите картину. Политика гарантирует, что вам не нужно слишком много дорогих операций, которые я описал выше.
StringBuilderэто класс, который в основном перераспределяет основной буфер в степени два. string.Formatиспользует StringBuilderпод капотом.
Это делает ваше решение основным компромиссом между overallocate-and-append (-multiple) (w / wo culture) или просто «распределить-и-добавить».
string.Format, который не использует какие-либо составные функции форматирования (то есть просто простые{0}) и заменить их значительно более быстрой конкатенацией строк. Интересно, что такой подвиг достижим с существующим переписчиком IL, таким как PostSharp.