Для простого випадку, коли це проста одинарна конкатенація, я вважаю, що це не варто складності 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";