Для простого случая, когда это простая одиночная конкатенация, я чувствую, что она не стоит сложности string.Format
(и я не проверял, но подозреваю, что для простого случая, подобного этому, string.Format
может быть немного медленнее, чем при разборе строки формата и все). Как и Джон Скит, я предпочитаю не вызывать явно .ToString()
, поскольку это будет сделано неявно из-за перегрузки string.Concat(string, object)
, и я думаю, что код выглядит чище и его легче читать без него.
Но для более чем нескольких конкатенаций (сколько субъективно) я определенно предпочитаю string.Format
. В какой-то момент я думаю, что и читаемость, и производительность неоправданно страдают от конкатенации.
Если в строке формата есть много параметров (опять же, «много» субъективно), я обычно предпочитаю включать закомментированные индексы в аргументы замены, чтобы не потерять отслеживание того, какое значение идет к какому параметру. Придуманный пример:
Console.WriteLine(
"Dear {0} {1},\n\n" +
"Our records indicate that your {2}, \"{3}\", is due for {4} {5} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Veterinary",
/*0*/client.Title,
/*1*/client.LastName,
/*2*/client.Pet.Animal,
/*3*/client.Pet.Name,
/*4*/client.Pet.Gender == Gender.Male ? "his" : "her",
/*5*/client.Pet.Schedule[0]
);
Обновление
Мне приходит в голову, что приведенный мною пример немного сбивает с толку, поскольку кажется, что я использовал и конкатенацию, и string.Format
здесь. И да, логически и лексически, это то, что я сделал. Но все объединения будут оптимизированы компилятором 1 , поскольку все они являются строковыми литералами. Таким образом, во время выполнения будет одна строка. Поэтому я должен сказать, что предпочитаю избегать многих конкатенаций во время выполнения .
Конечно, большая часть этой темы сейчас устарела, если только вы не застряли на C # 5 или старше. Теперь у нас есть интерполированные строки , которые по читаемости намного превосходят string.Format
почти во всех случаях. В наши дни, если только я не конкатенирую значение непосредственно в начало или конец строкового литерала, я почти всегда использую интерполяцию строк. Сегодня я напишу свой предыдущий пример так:
Console.WriteLine(
$"Dear {client.Title} {client.LastName},\n\n" +
$"Our records indicate that your {client.Pet.Animal}, \"{client.Pet.Name}\", " +
$"is due for {(client.Pet.Gender == Gender.Male ? "his" : "her")} " +
$"{client.Pet.Schedule[0]} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Veterinary"
);
Таким образом вы теряете конкатенацию во время компиляции. Каждая интерполированная строка преобразуется компилятором в вызов string.Format
, и их результаты объединяются во время выполнения. Это означает, что это жертва производительности во время выполнения для удобства чтения. В большинстве случаев это оправданная жертва, потому что штраф за время выполнения ничтожно мал. Однако в коде, критичном к производительности, может потребоваться профилирование различных решений.
1
Вы можете увидеть это в спецификации C # :
... в константных выражениях допускаются следующие конструкции:
...
- Предопределенный бинарный оператор + ... ...
Вы также можете проверить это с помощью небольшого кода:
const string s =
"This compiles successfully, " +
"and you can see that it will " +
"all be one string (named `s`) " +
"at run time";