StringBuilder:StringBuilder的长度和容量是否可以超过其MaxCapacity?

5
在向StringBuilder追加字符串的过程中,它的容量和长度是否可以超过其MaxCapacity?
根据MSDN的定义,“MaxCapacity是StringBuilder实例可以容纳的最大字符数”。但是以下两个代码片段的行为是不一致的:
代码片段1: 在下面的代码中,当StringBuilder的长度超过其MaxCapacity时,会抛出ArgumentOutOfRangeException异常 - 这是预期的行为。
        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

代码段2:在下面的代码中,当StringBuilder的长度超过其MaxCapacity时,不会抛出ArgumentOutOfRangeException异常- 此行为似乎是不正确的。
        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"

请问有人能解释一下这两种情况中发生了什么以及为什么行为不同吗?


请查看此链接:https://msdn.microsoft.com/zh-cn/library/system.text.stringbuilder.maxcapacity(v=vs.110).aspx - Nikita Shrivastava
1
StringBuilder的容量从0开始而不是1。0 + "1" + "12" + "123" = 6 - Gregg
1
有趣。如果你尝试 StringBuilder sb = new StringBuilder(0, 5);,第二个示例会抛出异常。 - Amit Kumar Ghosh
嗯!但是没有明确的指南。 - Amit Kumar Ghosh
如果你从手表上看这个问题,你会发现随着长度的增加,容量可能会增加,但最大容量仍然保持不变。 - Gregg
显示剩余3条评论
2个回答

8

StringBuilder构造函数 (Int32, Int32)

调用者注意事项
在.NET Framework 4和.NET Framework 4.5中,通过调用StringBuilder(Int32, Int32) 构造函数实例化StringBuilder对象时,StringBuilder实例的长度和容量都可以超出其MaxCapacity属性的值。特别是当您调用Append和AppendFormat方法来追加小字符串时可能会发生这种情况。

额外资源:

结论:

这个类为了性能原因而被写成这样,并且在官方文件中指出,当追加小字符串时,它的CapacityLength可以超出其MaxCapacity。此外,在文档中指出,一些默认值是实现特定的,因此似乎最好不要依赖于CapacityMaxCapacity,并且仅在以下条件下使用该类以提高性能:

  • 当您预计您的应用程序在设计时对字符串进行未知数量的更改(例如,当您使用循环来连接包含用户输入的随机数量的字符串时)。
  • 当您预计您的应用程序将对字符串进行大量更改时。

我猜实际上这意味着只要当前的Length小于MaxCapacity,就可以将内容追加到StringBuilder中。鉴于这是在版本4中进行的更改,很可能有充分的理由支持这样做。 - jmcilhinney
@HenkHolterman 我猜开发人员看到了它的用例,否则他们就不会添加它了。 - Rawling
@Reza:'MaxCapacity'属性有什么特定的用途吗?是否有任何文件定义容量何时可以超过'MaxCapacity',何时不能?根据问题中给出的示例-行为是不明确的。在其中一种情况下,当我尝试附加一个带有单个字符的字符串(并将'Capacity'增加到'MaxCapacity'之上)时,不会抛出异常,但在另一种情况下,当我尝试附加一个带有两个或更多字符的字符串时,就会抛出异常。 - manjuv
我猜这样做是出于性能原因(StringBuilder存在是为了避免更改不可变字符串的性能损失)。这并不是世界末日,对吧?这种行为已经有文档记录了;如果你准备捕获异常,那么检查长度会更有效率。 - Tim Long

0

Microsoft文档

当StringBuilder对象达到最大容量时,无法再为其分配更多内存,尝试添加字符或将其扩展超过其最大容量会引发ArgumentOutOfRangeException或OutOfMemoryException异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接