How to append two stringBuilders?
Asked Answered
A

6

60

Is there a way to append two string builders? And if so - does it perform better than appending a string to a StringBuilder ?

Affiant answered 23/6, 2011 at 13:0 Comment(2)
stringBuilder1.Append(stringBuilder2.ToString()); dotnetperls.com/stringbuilder-1Suchta
I think this Question is not named as it should be !Alwin
R
24

Just like that....

StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder();
sb.Append(sb1.ToString());
Revest answered 23/6, 2011 at 13:3 Comment(1)
That's appending a string to a sb. I thought to append to sb to avoid sealing sb to stringAffiant
P
43

I know this is three years later, but the .NET 4 StringBuilder behaves differently anyway.

Nevertheless, it does still come back to "what do you want to do?" Are you looking for simply the most performant way of appending two StringBuilders and continuing on with just the latter result? Or are you expecting to continue working with the existing buffered value of the appended StringBuilder?

For the former, and always in .NET 4,

frontStringBuilder.Append(backStringBuilder);

is best.

For the latter scenario in .NET 2/3.5,

frontStringBuilder.Append(backStringBuilder.ToString(0, backStringBuilder.Length));

is best (and won't hurt performance in .NET 4).

Pertinacious answered 9/7, 2014 at 6:4 Comment(6)
Very clear answer. I thought it could be worth adding that .AppendLine() does NOT provide the same flexibility, in case anyone wonders.Forbidding
@CharlesRobertoCanato I'm not sure what you mean: .AppendLine is implemented as .Append(string) followed by .Append(NewLine) for both .NET 2.0/3.5 and 4, which means both of the scenarios above are the same.Pertinacious
Sorry @MarkHurd I wasn't clear enough: what I meant is, although .ApppendLine is really implemented as you described, it only accepts String as a parameter in any .NET versions. So, even in .NET 4, you can't just do a .AppendLine( backStringBuilder ) - what I meant with "lacking flexibility". Not a problem, just a note - it's only an extra method call, anyway.Forbidding
@CharlesRobertoCanato Actually, you're highlighting a recent change to the code: I removed the explicit .ToString because, as Nigrimmist mentions in his answer, .ToString is currently implied and, in the future, maybe there will be an overload that does accept a StringBuilder directly.Pertinacious
under the hood frontStringBuilder.Append(backStringBuilder) calls backStringBuilder.toString() inside. so it's basically frontStringBuilder.Append(backStringBuilder.ToString()) .Q
@Q Yes, that's what I had until Nigrimmist pointed out that it would be better for future possibilities of a StringBuilder direct overload were to become available.Pertinacious
R
24

Just like that....

StringBuilder sb = new StringBuilder();
StringBuilder sb1 = new StringBuilder();
sb.Append(sb1.ToString());
Revest answered 23/6, 2011 at 13:3 Comment(1)
That's appending a string to a sb. I thought to append to sb to avoid sealing sb to stringAffiant
L
19

This will do it without allocations

StringBuilder sb = new StringBuilder("aaaa");    
StringBuilder second = new StringBuilder("bbbbb");
sb.EnsureCapacity(sb.Length + second.Length);
for (int i = 0; i < second.Length; i++)
{
    sb.Append(second[i]);
}
Leary answered 22/2, 2013 at 9:52 Comment(1)
Unfortunately the indexer property in StringBuilder is non-trivial and actually iterates over each "chunk" inside the StringBuilder for every access, making this somewhat expensive to use in a loop. For my implementation I used a reusable Char[] buffer if the StringBuilder is more than ~4,000 characters long.Pulling
I
14

You don't need to call .ToString(). You should simply append one to another. That's all. It will be better against direct .ToString() call for next reason :

1) StringBuilder does not have constructor with StringBuilder as a param, string, int/string etc. StringBuilder overriding .ToString() and as a result :

StringBuilder sb1 = new StringBuilder("1");
sb1.Append(new StringBuilder("2"));
Console.WriteLine(sb1);

that code will call overrided version of .ToString() automatically. Output will be "12";

2)If StringBuilder will be added as incoming param to StringBuilder constructor's in next framework versions, your code will be clear and ready for correct appending without any refactoring.

Have a good day!

Impose answered 7/5, 2015 at 11:23 Comment(1)
Great suggestion and clean understandible codingFarant
O
6

If the StringBuilder is large, then this will minimize string-allocations (especially if you can provide a reusable char-buffer):

    public static void CopyTo(this StringBuilder source, StringBuilder dest)
    {
        char[] buffer = new char[Math.Min(source.Length, 1024)];
        CopyTo(source, dest, buffer);
    }

    public static void CopyTo(this StringBuilder source, StringBuilder dest, char[] buffer)
    {
        dest.EnsureCapacity(dest.Length + source.Length);
        for (int i = 0; i < source.Length; i += buffer.Length)
        {
            int charCount = Math.Min(source.Length - i, buffer.Length);
            source.CopyTo(i, buffer, 0, charCount);
            dest.Append(buffer, 0, charCount);
        }
    }
Ordnance answered 2/4, 2017 at 19:4 Comment(0)
S
4

Simply as that:

firstStringBuilder.Append(secondStringBuilder.ToString());
Solicitude answered 23/6, 2011 at 13:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.