Вывод строки: формат или конкат в C #? - PullRequest
175 голосов
/ 19 августа 2008

Допустим, вы хотите вывести или объединить строки. Какой из следующих стилей вы предпочитаете?

  • var p = new { FirstName = "Bill", LastName = "Gates" };

  • Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

  • Console.WriteLine(p.FirstName + " " + p.LastName);

Вы предпочитаете использовать формат или просто строки? Что твое любимое? Один из них болит твои глаза?

Есть ли у вас рациональные аргументы в пользу использования одного, а не другого?

Я бы пошел на второй.

Ответы [ 31 ]

5 голосов
/ 19 августа 2008

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

Другим преимуществом является, я полагаю, одно из преимуществ производительности, поскольку последний фактически выполняет 2 оператора создания строки перед передачей окончательной строки в метод Console.Write. Я полагаю, что String.Format использует StringBuilder под крышками, поэтому многократных конкатенаций избегают.

Следует отметить, однако, что если параметры, которые вы передаете в String.Format (и другие такие методы, как Console.Write), являются типами значений, то перед передачей они будут помещены в коробку, что может обеспечить собственные потери производительности. Сообщение в блоге об этом здесь .

5 голосов
/ 12 августа 2015

Через неделю, 19 августа 2015 года, этому вопросу будет ровно семь (7) лет. Теперь есть лучший способ сделать это. Лучше с точки зрения удобства сопровождения, поскольку я не проводил никакого теста производительности по сравнению с простым конкатенацией строк (но имеет ли это значение в наши дни - разница в несколько миллисекунд?). Новый способ сделать это с C # 6.0 :

var p = new { FirstName = "Bill", LastName = "Gates" };
var fullname = $"{p.FirstName} {p.LastName}";

Эта новая функция лучше , IMO и на самом деле лучше в нашем случае , поскольку у нас есть коды, в которых мы строим строки запросов, значения которых зависят от некоторых факторов. Представьте себе одну строку запроса, где у нас есть 6 аргументов. Так что вместо того, чтобы сделать, например:

var qs = string.Format("q1={0}&q2={1}&q3={2}&q4={3}&q5={4}&q6={5}", 
    someVar, anotherVarWithLongName, var3, var4, var5, var6)

в может быть написано так, и это легче читать:

var qs=$"q1={someVar}&q2={anotherVarWithLongName}&q3={var3}&q4={var4}&q5={var5}&q6={var6}";
5 голосов
/ 08 августа 2015

Начиная с C # 6.0 для этого можно использовать интерполированные строки , что еще больше упрощает формат.

var name = "Bill";
var surname = "Gates";
MessageBox.Show($"Welcome to the show, {name} {surname}!");

Интерполированное строковое выражение выглядит как шаблонная строка, содержащая выражения. Интерполированное строковое выражение создает строку, заменяя содержащиеся выражения на представления ToString результатов выражений.

Интерполированные строки имеют производительность, аналогичную String.Format, но улучшают читаемость и сокращают синтаксис из-за того, что значения и выражения вставляются в строку.

Пожалуйста, также обратитесь к этой статье dotnetperls об интерполяции строк.

Если вы ищете способ форматирования строк по умолчанию, это имеет смысл с точки зрения читабельности и производительности (за исключением случаев, когда микросекунды будут иметь значение в вашем конкретном случае использования).

5 голосов
/ 22 сентября 2008

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

StringBuilder и String.Format, хотя и могут работать медленнее, но более эффективно работают с памятью.

Что плохого в конкатенации строк?

4 голосов
/ 19 августа 2008
  1. Форматирование - это «.NET» способ сделать это. Некоторые инструменты рефакторинга (Refactor! For one) даже предложат рефакторинг кода в стиле concat для использования стиля форматирования.
  2. Форматирование легче оптимизировать для компилятора (хотя второе, вероятно, будет реорганизовано для использования быстрого метода Concat).
  3. Форматирование обычно более читабельно (особенно при «необычном» форматировании).
  4. Форматирование означает неявные вызовы '.ToString' для всех переменных, что хорошо для удобства чтения.
  5. Согласно «Effective C #», реализации .NET «WriteLine» и «Format» перепутаны, они автоматически блокируют все типы значений (что плохо). «Эффективный C #» советует явно выполнять вызовы «.ToString», что, по моему мнению, является поддельным (см. сообщение Джеффа )
  6. На данный момент подсказки типа форматирования не проверяются компилятором, что приводит к ошибкам во время выполнения. Однако это может быть исправлено в будущих версиях.
4 голосов
/ 19 августа 2008

Я бы использовал String.Format, но у меня также была бы строка формата в файлах ресурсов, чтобы ее можно было локализовать для других языков. Использование простой строки concat не позволяет вам сделать это. Очевидно, что если вам никогда не понадобится локализовать эту строку, это не повод задуматься. Это действительно зависит от того, для чего предназначена строка.

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

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

Если бы он создавал запрос, подобный SQL, я бы использовал Linq .

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

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

3 голосов
/ 07 июня 2009

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

3 голосов
/ 13 мая 2009

Я выбираю на основе читабельности. Я предпочитаю вариант форматирования, когда вокруг переменных есть текст. В этом примере:

Console.WriteLine("User {0} accessed {1} on {2}.", 
                   user.Name, fileName, timestamp);

вы понимаете значение даже без имен переменных, тогда как конкат загроможден кавычками и знаками + и смущает мои глаза:

Console.WriteLine("User " + user.Name + " accessed " + fileName + 
                  " on " + timestamp + ".");

(я позаимствовал пример Майка, потому что он мне нравится)

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

   Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

Параметр форматирования позволяет мне прочитать имена переменных и сопоставить их с соответствующими числами. Для параметра concat этого не требуется. Меня все еще смущают кавычки и знаки +, но альтернатива еще хуже. Рубин

   Console.WriteLine(p.FirstName + " " + p.LastName);

С точки зрения производительности, я ожидаю, что параметр форматирования будет медленнее, чем concat, поскольку для формата требуется, чтобы строка была проанализирована . Я не помню, чтобы мне приходилось оптимизировать такие инструкции, но если бы я это сделал, я бы посмотрел на string методы, такие как Concat() и Join().

Другое преимущество формата заключается в том, что строку формата можно поместить в файл конфигурации. Очень удобно с сообщениями об ошибках и текстом пользовательского интерфейса.

3 голосов
/ 22 сентября 2008

Если вы имеете дело с чем-то, что должно быть легко читаемым (а это большая часть кода), я бы придерживался версии перегрузки оператора UNLESS:

  • Код должен быть выполнен миллионы раз
  • Вы делаете тонны конкататов (более 4 - это тонна)
  • Код предназначен для Compact Framework

По крайней мере при двух из этих обстоятельств я бы вместо этого использовал StringBuilder.

2 голосов
/ 19 августа 2008

Я предпочитаю и второе, но у меня нет рациональных аргументов в поддержку этого положения.

...