Как я должен объединить строки? - PullRequest
17 голосов
/ 23 июня 2010

Есть ли различия между этими примерами? Что я должен использовать в этом случае?

var str1 = "abc" + dynamicString + dynamicString2;

var str2 = String.Format("abc{0}{1}", dynamicString, dynamicString2);

var str3 = new StringBuilder("abc").
    Append(dynamicString).
    Append(dynamicString2).
    ToString();

var str4 = String.Concat("abc", dynamicString, dynamicString2);

Есть похожие вопросы:

Этот вопрос задает вопрос о том, что происходит в каждом случае, каков будет реальный результат этих примеров? Каковы различия о них? Где я должен использовать их в этом случае?

Ответы [ 9 ]

16 голосов
/ 23 июня 2010

Пока вы не работаете с очень многими (100+) строками или с очень большими (длина> 10000) строками, единственным критерием является удобочитаемость.

Для задач такого размера используйте +.Эта перегрузка + была добавлена ​​в класс строк для удобства чтения.

Используйте string.Format() для более сложных композиций и когда требуются замены или форматирование.

Используйте StringBuilder при объединении множества кусков (сотен или более) или очень больших кусков (длина >> 1000).StringBuilder не имеет функций читабельности, он просто для повышения производительности.

8 голосов
/ 23 июня 2010

Собирая информацию из всех ответов, получается, что она ведет себя так:

Оператор + такой же, как String.Concat, он может использоваться для небольших объединений вне цикла, может использоваться для небольших задач.

Во время компиляции оператор + генерирует одну строку, если они являются статическими, в то время как String.Concat генерирует выражение str = str1 + str2;, даже если они являются статическими.

String.Format совпадает с StringBuilder.. (пример 3), за исключением того, что String.Format выполняет проверку параметров и создает внутренний StringBuilder с длиной параметров.

String.Format следует использовать при необходимости форматирования строки и для объединения простых строк.

StringBuilder следует использовать, когда вам нужно объединить большие строки или в цикле.

5 голосов
/ 23 июня 2010

Используйте оператор + в вашем сценарии.

Я бы использовал метод String.Format () только в том случае, если в вашей строке содержится смесь переменных и статических данных. Например:

string result=String.Format(
    "Today {0} scored {1} {2} and {3} points against {4}",..);

//looks nicer than
string result = "Today " + playerName + " scored " + goalCount + " " + 
    scoreType + " and " + pointCount + " against " + opposingTeam;

Я не вижу смысла в использовании StringBuilder, поскольку вы уже имеете дело с тремя строковыми литералами.

Лично я использую Concat только при работе с массивом String.

2 голосов
/ 23 июня 2010

Мое эмпирическое правило состоит в том, чтобы использовать String.Format, если вы делаете относительно небольшое количество конкатенации (<100) и <code>StringBuilder для случаев, когда конкатинация будет большой или потенциально может быть большой.Я использую String.Join, если у меня есть массив и не требуется никакого форматирования.

Вы также можете использовать функцию агрегирования в LINQ, если у вас есть перечисляемая коллекция: http://msdn.microsoft.com/en-us/library/bb548651.aspx

1 голос
/ 23 июня 2010

@ Ксандер. Я верю тебе, парень. Однако мой код показывает, что sb быстрее, чем string.format.

Удар это:

Stopwatch sw = new Stopwatch();
sw.Start();

for (int i = 0; i < 10000; i++)
{
    string r = string.Format("ABC{0}{1}{2}", i, i-10, 
        "dasdkadlkdjakdljadlkjdlkadjalkdj");
}

sw.Stop();
Console.WriteLine("string.format: " + sw.ElapsedTicks);

sw.Reset();
sw.Start();
for (int i = 0; i < 10000; i++)
{
    StringBuilder sb = new StringBuilder();
    string r = sb.AppendFormat("ABC{0}{1}{2}", i, i - 10,
        "dasdkadlkdjakdljadlkjdlkadjalkdj").ToString();
}

sw.Stop();
Console.WriteLine("AppendFormat: " + sw.ElapsedTicks);
1 голос
/ 23 июня 2010

@ Jerod Houghtelling Ответ

На самом деле String.Format использует StringBuilder за кулисами (используйте отражение на String.Format, если хотите)

Я согласен сследующий ответ в общем

0 голосов
/ 09 августа 2010

Важно помнить, что строки не ведут себя как обычные объекты. Возьмите следующий код:

string s3 = "Hello ";
string s3 += "World";

Этот фрагмент кода создаст новую строку в куче и поместит в нее «Hello». Ваш строковый объект в стеке будет указывать на него (как обычный объект).

Строка 2 создаст вторую строку в куче «Hello World» и укажет на нее объект в стеке. Первоначальное выделение стека все еще остается до тех пор, пока не будет вызван сборщик мусора.

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

0 голосов
/ 24 июня 2010

Важно понимать, что строки неизменны, они не меняются. Поэтому в ЛЮБОЕ время, когда вы изменяете, добавляете, модифицируете или что-то еще, строка создает новую «версию» строки в памяти, а затем отдает старую версию для сборки мусора. Так что-то вроде этого:

string output = firstName.ToUpper().ToLower() + "test";

Это создаст строку (для вывода), затем создаст ТРИ другие строки в памяти (одну для: ToUpper (), ToLower () для вывода, а затем одну для объединения "test").

Так что, если вы не используете StringBuilder или string.Format, все, что вы делаете, будет создавать дополнительные экземпляры вашей строки в памяти. Это, конечно, проблема внутри цикла, где вы можете получить сотни или тысячи дополнительных строк. Надеюсь, это поможет

0 голосов
/ 23 июня 2010
var str3 = new StringBuilder
    .AppendFormat("abc{0}{1}", dynamicString, dynamicString2).ToString(); 

код выше самый быстрый. так что пользуйтесь если хотите быстро. используйте что-нибудь еще, если вам все равно.

...