能否独立于Capacity控制StringBuilder扩容的增量大小?
当StringBuilder为容纳更长字符串而扩容时,能否独立于Capacity控制扩容的增量大小?
以下代码演示了当前问题:StringBuilder会以初始Capacity为基准进行扩容,仅添加一个字符就会使容量翻倍。
Imports System.Text Module Module1 Public Sub main() Dim sb As StringBuilder = New StringBuilder(64) Dim str As String str = StrDup(64, "x") sb.Append(str) '64字符 Console.WriteLine("Results:") Console.WriteLine("{0,-68} Capacity={1}", sb.ToString, sb.Capacity.ToString) sb.Append("y") '再添加一个字符 Console.WriteLine("{0,-68} Capacity={1}", sb.ToString, sb.Capacity.ToString) Console.WriteLine("Press any key to close.") Console.ReadKey() End Sub End Module
运行结果:
Results: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Capacity=64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy Capacity=128 Press any key to close.
但如果需要大初始容量,同时只需要小幅度扩容呢?例如,StringBuilder(16384)会扩容至32768,但我仅需要16或32这样的小增量。能否修改扩容增量,而非依赖Capacity()?
另外,在文档中看到如下注释,这是否与需求相关?
在.NET Core及.NET Framework 4.0及更高版本中,当通过调用StringBuilder(Int32, Int32)构造函数实例化StringBuilder对象时,其长度和容量都可能超过MaxCapacity属性的值,在调用Append(String)和AppendFormat(String, Object)方法追加短字符串时尤其容易出现这种情况。
核心结论
.NET的StringBuilder没有内置API可以直接修改默认的扩容增量逻辑(默认按当前容量的倍数扩容,通常是翻倍)。但你可以通过**手动提前设置Capacity**来实现小幅度扩容的需求。
解决方案:手动控制容量
在每次追加内容前,预估需要的总长度,若当前容量不足,直接将Capacity设置为「当前长度 + 你需要的增量值」(比如16或32),这样就能避免StringBuilder自动翻倍扩容。
示例代码修改如下:
Imports System.Text Module Module1 Public Sub main() Dim sb As StringBuilder = New StringBuilder(64) Dim str As String = StrDup(64, "x") sb.Append(str) Console.WriteLine("Results:") Console.WriteLine("{0,-68} Capacity={1}", sb.ToString, sb.Capacity.ToString) ' 手动控制扩容增量:需要添加1个字符,设置容量为当前长度+16(自定义增量) If sb.Length + 1 > sb.Capacity Then sb.Capacity = sb.Length + 16 End If sb.Append("y") Console.WriteLine("{0,-68} Capacity={1}", sb.ToString, sb.Capacity.ToString) Console.WriteLine("Press any key to close.") Console.ReadKey() End Sub End Module
运行结果会变成:
Results: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Capacity=64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy Capacity=80 Press any key to close.
关于文档注释的说明
你看到的那段注释和你的需求无关。它描述的是一种特殊场景:当用StringBuilder(Int32, Int32)(指定初始容量和最大容量)实例化对象时,在追加短字符串时,可能出现长度和容量临时超过MaxCapacity的情况,这和扩容增量的控制没有关系。
内容的提问来源于stack exchange,提问作者spinjector

