Поскольку я не думаю, что ответы здесь охватывают все, я хотел бы сделать небольшое дополнение здесь.
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.