由于 String 类型代表不可变字符串,所以 FCL 提供了 System.Text.StringBuilder 类型对字符串和字符进行高效动态处理,并返回处理好的 String 对象。可将 StringBuilder 想象成创建 String 对象的特殊构造器。你的方法一般应获取 String 参数而非 StringBuilder 参数。
从逻辑上说, StringBuilder 对象包含一个字段,该字段引用了由 Char 结构构成的数组。可利用 StringBuilder 的各个成员来操纵该字符数组,高效率地缩短字符串或更改字符串中的字符。如果字符串变大,超过了事先分配的字符数组大小,StringBuilder 会自动分配一个新的、更大的数组,赋值字符,并开始使用新数组。前一个数组被垃圾回收。
用 StringBuilder 对象构造好字符串后,调用 StringBuilder 的 ToString 方法即可将 StringBuilder 的字符数组“转换”成 String 。这样会在堆上新建 String 对象,其中包含调用 ToString 时存在于 StringBuilder 中的字符串。之后可继续处理 StringBuilder 中的字符串。以后可再次调用 ToString 把它转换成另一个 String 对象。
//--构造 StringBuilder 对象
和 String 类不同,CLR不觉得 StringBuilder 类有什么特别。此外,大多数语言(包括C#)都不降 StringBuilder 类视为基元类型。要像构造其他任何非基元类型那样构造 StringBuilder 对象:
StringBuilder 类型提供了许多构造器。每个构造器的职责是分配和初始化由每个 StringBuilder 对象维护的状态。
1.最大容量
一个 Int32 值,指定了能放到字符串中的最大字符数。默认值是 Int32.MaxValue(约20亿)。一般不用更改这个值,但有时需要指定较小的最大容量以确保永远不会创建超出特定长度的字符串、构造好之后。这个 StringBuilder 的最大容量就固定下来了,不能再变。
2.容量
一个 Int32 值,指定了由 StringBuilder 维护的字符数组的长度。默认为16.如果事先知道要在这个 StringBuilder 中放入多少字符,那么构造 StringBuilder 对象时应该自己设置容量。
向字符数组追加字符时,StringBuilder 会检测数组会不会超过设定的容量。如果会,StringBuilder 会自动倍增容量字段,用新容量来分配新数组,并将原始数组的字符赋值到新数组中。随后,原始数组可以被垃圾回收。数组动态扩容会损害性能。要避免就要设置一个合适的初始容量。
3.字符数组
一个由 Char 结构构成的数组,负责维护“字符串”的字符内容。字符数总是小于或等于“容量”和“最大容量”值。可用 StringBuilder 的 Length 属性来获取数组中已经使用的字符数。 Lengh 总是小于或等于 StringBuilder 的“容量”值。可在构造 StringBuilder 时传递一个 String 来初始化字符数组。不传递字符串,数组刚开始不包含任何字符---即 Length 属性返回0。
//--StringBuilder 的成员
和 String 不同,StringBuilder 代表可变(mutable)字符串。也就是说,StringBuilder 的大多数成员都能改变字符数组的内容,同时不会造成在托管堆上分配新对象。StringBuilder 只有以下两种情况会分配新对象。
1.动态构造字符串,其长度超过了设置的“容量”。
2.调用 StringBuilder 的 ToString 方法。
//--
成员名称 | 成员类型 | 说明 |
---|---|---|
MaxCapacity | 只读属性 | 返回字符串能容纳的最大字符数(最大容量)。 |
Capacity | 可读/可写属性 | 获取或设置字符数组的长度(容量)。将容量设得比字符串长度小或者比 MaxCapacity 大将抛出 ArgumentOutOfRangeException 异常。 |
EnsureCapacity | 方法 | 保证字符数组至少具有指定的长度(容量)。如果传给方法的值大于 StringBuilder 的当前容量,当前容量会自动增大。如果当前容量已大于传给该方法的值,则不发生任何变化。 |
Length | 可读/可写属性 | 获取或设置“字符串”中的字符数。它可能小于字符数组的当前容量。将这个属性设为0,会将 StringBuilder 的内容置为空字符串。 |
ToString | 方法 | 这个方法的无参版本返回代表 StringBuilder 的字符数组的一个 String 。 |
Chars | 可读/可写 索引器属性 | 获取或设置字符数组指定索引位置的字符。在C#中,这是一个索引器(有参属性),要用数组语法([ ])来访问。 |
Clear | 方法 | 清除 StringBuilder 对象的内容,等同于把它的 Length 属性设为0。 |
Append | 方法 | 在字符数组末尾追加一个对象;如有必要,数组会进行扩充。使用常规格式和与调用线程关联的语言文化将对象转换成字符串。 |
Insert | 方法 | 在字符数组中插入一个对象;如有必要,数组会进行扩充。使用常规格式和与调用线程关联的语言文化将对象转换成字符串。 |
AppendFormat | 方法 | 在字符数组末尾追加指定的零个或多个对象;如有必要,数组会进行扩充。使用调用者提供的格式化和语言文化信息,将这些对象转换成字符串。AppendFormat 是处理 StringBuilder 对象时最常用的方法之一。 |
AppendLine | 方法 | 在字符数组末尾追加一个行中止符或者一个带行中止符的字符串;如有必要,数组会进行扩充。 |
Replace | 方法 | 将字符数组的一个字符替换成另一个字符,或者将一个字符串替换成另一个字符串。 |
Remove | 方法 | 从字符数组中删除指定范围的字符。 |
Equals | 方法 | 只有两个 StringBuilder 对象具有相同最大容量、字符数组容量和字符内容才返回 true。 |
CopyTo | 方法 | 将 StringBuilder 的字符内容的一个子集复制到一个 Char 数组中。 |
使用 StringBuilder 的方法要注意,大多数方法返回的都是对同一个 StringBuilder 对象的引用,所以几个操作能连接到一起完成:
String 和 StringBuilder 类提供的方法并不完全对应。所以有时需要在 String 和 StringBuilder 之间转换以完成特定任务。