5

While appending strings to a StringBuilder, can its Capacity and Length go beyond its MaxCapacity?

According to MSDN MaxCapacity is defined as "The maximum number of characters string builder instance can hold". But this behaviour is inconsistent in below two code snippets:

Snippet 1: In the below code ArgumentOutOfRangeException is thrown when the length of the StringBuilder exceeds its MaxCapacity - This is as expected.

        String str = sb.ToString();

        StringBuilder sb1 = new StringBuilder(3, 5);
        sb1.Append("1");      //no error as Length 1 <= max limit 5         
        sb1.Append("12");     //no error as Length 3 <= max limit 5           
        sb1.Append("123");    //ArgumentOutOfRangeException Thrown as Length 6 > max limit 5

Snippet 2: In the below code NO ArgumentOutOfRangeException is thrown when the length of the StringBuilder exceeds its MaxCapacity - This behaviour seems to be incorrect.

        StringBuilder sb = new StringBuilder(3, 5);

        sb.Append("1"); //no error as Length 1 <= max limit 5         
        sb.Append("2"); //no error as Length 2 <= max limit 5         
        sb.Append("3"); //no error as Length 3 <= max limit 5         
        sb.Append("4"); //no error as Length 4 <= max limit 5         
        sb.Append("5"); //no error as Length 5 <= max limit 5         
        sb.Append("6"); //Even though Length 6 > max limit 5 NO EXCEPTION IS THROWN         

        String str = sb.ToString(); //Contains "123456"

Can anyone please explain whats happening in these two cases and why is the difference in the behavior?

8
  • check this link : msdn.microsoft.com/en-us/library/… Commented Sep 7, 2015 at 6:50
  • 1
    The StringBuilder capacity is starting at 0 not 1. 0 + "1" + "12" + "123" = 6
    – Gregg
    Commented Sep 7, 2015 at 6:56
  • 1
    Interesting. if you try StringBuilder sb = new StringBuilder(0, 5);, the second sample throws. Commented Sep 7, 2015 at 6:58
  • @Nikita - nothing special there. Commented Sep 7, 2015 at 7:02
  • @Gregg - I tried StringBuilder sb = new StringBuilder(3, 5); sb.Append("1"); sb.Append("21"); sb.Append("32"); sb.Append("4"); doesn't throw. Commented Sep 7, 2015 at 7:02

2 Answers 2

8

StringBuilder Constructor (Int32, Int32)

Notes to Callers
In the .NET Framework 4 and the .NET Framework 4.5, when you instantiate the StringBuilder object by calling the StringBuilder(Int32, Int32) constructor, both the length and the capacity of the StringBuilder instance can grow beyond the value of its MaxCapacity property. This can occur particularly when you call the Append and AppendFormat methods to append small strings.

Additional Resource:

Conclusion:

This class has written this way for performance reasons and as stated in official documents, its Capacity and Length can grow beyond the its MaxCapacity particularly when appending small strings. Furthermore as stated in documents, some of default values are implementation-specific and so It seems you better don't rely on Capacity and MaxCapacity, and only use this class for performance reasons these conditions:

  • When you expect your app to make an unknown number of changes to a string at design time (for example, when you are using a loop to concatenate a random number of strings that contain user input).
  • When you expect your app to make a significant number of changes to a string.
4
  • I'm guessing that what this means in practice is that you can append to a StringBuilder as long as the current Length is less than the MaxCapacity. There was presumably a good reason for it, given that it was a change made in version 4. Commented Sep 7, 2015 at 6:59
  • @HenkHolterman I presume the developers saw a use case for it, else they wouldn't have added it.
    – Rawling
    Commented Sep 7, 2015 at 7:26
  • @Reza : Is there any particular use of the 'MaxCapacity' property? Is there any document which defines when the capacity can exceed 'MaxCapacity' and when it cannot? As per the example given in the question - the behavior is ambiguous..In one of the scenario where I try to append a string with single character(and increase the 'Capacity' beyond the 'MaxCapacity') no exception is thrown but in the other case where I tried to append a string with two/more characters an exception is thrown.
    – manjuv
    Commented Sep 7, 2015 at 11:14
  • I would guess that it was done that way for performance reasons (StringBuilder exists to avoid the performance hit of changing immutable strings). It's not really the end of the world, is it? The behaviour is documented; if you're prepared to catch an exception then it's going to be more efficient to check the length.
    – Tim Long
    Commented Sep 7, 2015 at 13:26
0

Microsoft Document

When the maximum capacity is reached, no further memory can be allocated for the StringBuilder object, and trying to add characters or expand it beyond its maximum capacity throws either an ArgumentOutOfRangeException or an OutOfMemoryException exception.

Not the answer you're looking for? Browse other questions tagged or ask your own question.