Зачем использовать String.Format? [Дубликат]

139

Зачем кому-то использовать String.Format в С# и VB.NET в отличие от операторов конкатенации (& в VB и + в С#)?

В чем основное отличие? Почему все так заинтересованы в использовании String.Format? Мне очень любопытно.

Показать ещё 1 комментарий
Теги:

7 ответов

329
Лучший ответ

Я вижу несколько причин:

читаемость

string s = string.Format("Hey, {0} it is the {1}st day of {2}.  I feel {3}!", _name, _day, _month, _feeling);

против

string s = "Hey," + _name + " it is the " + _day + "st day of " + _month + ".  I feel " + feeling + "!";

Спецификаторы формата (и это включает в себя тот факт, что вы можете писать пользовательские форматы)

string s = string.Format("Invoice number: {0:0000}", _invoiceNum);

против

string s = "Invoice Number = " + ("0000" + _invoiceNum).Substr(..... /*can't even be bothered to type it*/)

Сохранение шаблона строки

Что делать, если я хочу хранить строковые шаблоны в базе данных? При форматировании строк:

_id         _translation
  1         Welcome {0} to {1}.  Today is {2}.
  2         You have {0} products in your basket.
  3         Thank-you for your order.  Your {0} will arrive in {1} working days.

против

_id         _translation
  1         Welcome
  2         to
  3         .  Today is
  4         . 
  5         You have
  6         products in your basket.
  7         Someone
  8         just shoot
  9         the developer.
  • 1
    Я согласен с обоими, но я думаю, что главная причина в том, что вы можете читать строку без шума имен переменных внутри.
  • 2
    Я не думаю, что разделение проблем, обеспечиваемое удалением шаблонов строк из вашего кода, следует недооценивать. Если какая-то плохая формулировка становится проблемой, это может означать разницу между простым изменением конфигурации или обновлением базы данных, и полномасштабным экстренным изменением.
Показать ещё 16 комментариев
73

Помимо того, что вам немного легче читать и добавлять еще несколько операторов, это также полезно, если ваше приложение интернационализировано. Много раз переменные представляют собой числа или ключевые слова, которые будут в другом порядке для разных языков. Используя String.Format, ваш код может оставаться неизменным, в то время как разные строки будут попадать в файлы ресурсов. Таким образом, код будет

String.Format(resource.GetString("MyResourceString"), str1, str2, str3);

Пока ваши строки ресурсов заканчиваются

Русский: "blah blah {0} blah blah {1} blah {2}"

Русский: "{0} blet blet blet {2} blet {1}"

Если у русских могут быть разные правила о том, как все будет рассмотрено, порядок отличается или структура предложения отличается.

  • 6
    +1 Я никогда не рассматривал приложение String.Format к локализации, пока не увидел это.
20

Во-первых, я нахожу

string s = String.Format(
    "Your order {0} will be delivered on {1:yyyy-MM-dd}. Your total cost is {2:C}.",
    orderNumber,
    orderDeliveryDate,
    orderCost
);

гораздо легче читать, писать и поддерживать, чем

string s = "Your order " +
           orderNumber.ToString() +
           " will be delivered on " +
           orderDeliveryDate.ToString("yyyy-MM-dd") +
           "." +
           "Your total cost is " +
           orderCost.ToString("C") + 
           ".";

Посмотрите, насколько более поддерживаемым является

string s = String.Format(
    "Year = {0:yyyy}, Month = {0:MM}, Day = {0:dd}",
    date
);

по альтернативе, где вам придется повторять date три раза.

Во-вторых, спецификаторы формата, которые String.Format обеспечивают, дают вам большую гибкость в отношении вывода строки способом, который легче читать, писать и поддерживать, чем просто использовать обычную старую конкатенацию. Кроме того, легче справиться с проблемами культуры с помощью String.Format.

В-третьих, когда производительность имеет значение, String.Format будет превосходить конкатенацию. За кулисами он использует StringBuilder и избегает проблемы Schlemiel the Painter.

  • 1
    Просто примечание: у Шлеймеля нет проблемы Painter с повторяющимися + в строке. Они скомпилированы в одну string.Concat Вызов string.Concat .
  • 0
    На самом деле string.Concat превосходит String.Format (по крайней мере, для одной короткой строки). Однако здесь задействовано много факторов (которые могут сделать один более эффективным, чем другой). В ситуациях, когда время выполнения будет иметь большое значение (повторение одной и той же операции бесчисленное количество раз), скорость, сохраненная с помощью string.Concat будет незначительной.
Показать ещё 2 комментария
14

Несколько причин:

  • String.Format() очень мощный. Вы можете использовать поставщиков форматов и простые форматные индикаторы (например, фиксированную ширину) прямо в строке формата.
  • Вы можете сделать некоторые мощные вещи, поместив строки формата в файлы конфигурации.
  • String.Format() часто работает быстрее, так как он использует StringBuilder и эффективный конечный автомат за кулисами, тогда как конкатенация строк в .Net относительно медленная. Это особенно верно, поскольку размер строки и количество замещаемых значений увеличивается.
  • String.Format() на самом деле более известен многим программистам, особенно тем, которые исходят из фона, который использует вариант старой функции C printf().

Наконец, не забывайте StringBuilder.AppendFormat(). String.Format() фактически использует этот метод за кулисами, и переход к StringBuilder напрямую может дать вам своего рода гибридный подход: явно использовать .Append() (аналогично конкатенации) для некоторых частей большой строки и использовать. AppendFormat() в других.

  • 3
    string.Format обычно не будет быстрее, чем несколько конкатенаций строк, потому что форматная строка также должна быть проанализирована и скопирована.
  • 0
    @ 0xA3 - Обновлено сообщение, чтобы отразить это несколько.
Показать ещё 2 комментария
5

String.Format добавляет множество опций в дополнение к операторам конкатенации, включая возможность указывать конкретный формат каждого элемента, добавленного в строку.

Подробнее о том, что возможно, я бы рекомендовал прочитать раздел в MSDN под названием Composite Formatting. В нем объясняется преимущество String.Format(а также xxx.WriteLine и других методов, поддерживающих составное форматирование) над обычными операторами конкатенации.

  • 2
    Формат строки хорош, но медленнее, чем конкатенация. достаточно сказано.
4

Там интересный материал по аспектам производительности в этом вопросе

Однако я лично по-прежнему рекомендую string.Format, если производительность не критична для удобства чтения.

string.Format("{0}: {1}", key, value);

Более читабельна, чем

key + ": " + value

Например. Также обеспечивает хорошее разделение проблем. Значит, вы можете иметь

string.Format(GetConfigValue("KeyValueFormat"), key, value);

И затем изменение вашего формата значения ключа с "{0}: {1}" до "{0} - {1}" становится изменением конфигурации, а не изменением кода.

string.Format также содержит кучу форматирования, встроенные в него, целые числа, форматирование даты и т.д.

  • 0
    Если вас интересует аспект производительности, вам может быть интересен другой вопрос: stackoverflow.com/questions/761121/…
2

Одна из причин не предпочтительнее писать строку типа 'string +"Value"+ string' из-за локализации. В случаях, когда происходит локализация, мы хотим, чтобы локализованная строка была правильно отформатирована, что может сильно отличаться от кодируемого языка.

Например, нам нужно показать следующую ошибку на разных языках:

MessageBox.Show(String.Format(ErrorManager.GetError("PIDV001").Description, proposalvalue.ProposalSource)

где

'ErrorCollector.GetError("ERR001").ErrorDescription' возвращает строку типа "Your ID {0} is not valid". Это сообщение должно быть локализовано на многих языках. В этом случае мы не можем использовать + в С#. Нам нужно следовать string.format.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню