C#中String和StringBuilder的区别

rat*_*tty 68 c# string stringbuilder

string和之间有什么区别StringBuilder

另外,理解的例子是什么?

Joe*_*oey 98

一个string实例是不可变的.创建后无法更改它.任何看似更改字符串的操作都会返回一个新实例:

string foo = "Foo";
// returns a new string instance instead of changing the old one
string bar = foo.Replace('o', 'a');
string baz = foo + "bar"; // ditto here
Run Code Online (Sandbox Code Playgroud)

不可变对象具有一些很好的属性,例如它们可以跨线程使用而不用担心同步问题,或者你可以直接分发你的私有支持字段,而不用担心有人更改了他们不应该改变的对象(参见数组或可变列表,如果不需要,通常需要在返回之前复制它们.但是当不小心使用时,它们可能会产生严重的性能问题(几乎任何事情 - 如果您需要一个以执行速度为傲的语言的示例,那么请查看C的字符串操作函数).

当你需要一个可变的字符串,比如你正在逐步构建的字符串或你改变很多东西的字符串时,那么你需要一个可以改变StringBuilder的字符缓冲区.这在很大程度上影响了性能.如果你想要一个可变的字符串而不是普通的实例,那么你最终会不必要地创建和销毁大量的对象,而实例本身会发生变化,从而无需使用许多新对象.stringStringBuilder

简单的例子:以下将使许多程序员痛苦地畏缩:

string s = string.Empty;
for (i = 0; i < 1000; i++) {
  s += i.ToString() + " ";
}
Run Code Online (Sandbox Code Playgroud)

你最终会在这里创建2001个字符串,其中2000个被丢弃.使用StringBuilder的相同示例:

StringBuilder sb = new StringBuilder();
for (i = 0; i < 1000; i++) {
  sb.Append(i);
  sb.Append(' ');
}
Run Code Online (Sandbox Code Playgroud)

这应该减少对内存分配器的压力:-)

但应该注意的是,C#编译器在字符串方面相当聪明.例如,以下行

string foo = "abc" + "def" + "efg" + "hij";
Run Code Online (Sandbox Code Playgroud)

将由编译器加入,在运行时只留下一个字符串.同样,行如

string foo = a + b + c + d + e + f;
Run Code Online (Sandbox Code Playgroud)

将改写为

string foo = string.Concat(a, b, c, d, e, f);
Run Code Online (Sandbox Code Playgroud)

所以你不必支付五个荒谬的连接,这将是处理它的天真方式.这不会像上面那样在循环中保存你(除非编译器展开循环,但我认为只有JIT可能实际上这样做而且最好不要赌它).

  • @Jeson:不可变数据结构有很多不错的属性,大多数都与默认编写更安全的代码有关.你不必担心你的字符串改变只是因为另一个线程在它们上工作.而且您不必返回类的内部字符串的副本,以防止消费者篡改您的字段. (3认同)
  • 人们可能想知道为什么字符串是"愚蠢的".. :) (2认同)

Han*_*son 6

字符串是不可变的,这意味着当您创建字符串时,您永远无法更改它.相反,它会创建一个新的字符串来存储新值,如果你需要经常更改字符串变量的值,这可能是低效的.

StringBuilder可用于模拟可变字符串,因此在需要更改字符串时很有用.


Sha*_*r K 6

String vs. StringBuilder

    • 在系统名称空间下
    • 不可变(只读)实例
    • 当值发生连续变化时,性能会下降

    • 线程安全

  • StringBuilder(可变字符串)

    1. 在System.Text命名空间下
    2. 可变实例
    3. 显示更好的性能,因为对现有实例进行了新的更改

有关使用ObjectIDGenerator的大量示例的有关此主题的描述性文章,请点击此链接.

相关的Stack Overflow问题:字符串在C#中没有变化时字符串的可变性


小智 6

细绳

String 实例是不可变的,这意味着我们在创建它之后就无法更改它。如果我们对字符串执行任何操作,它将返回一个新实例(在内存中创建一个新实例),而不是修改现有实例值。

字符串生成器

StringBuilder是可变的,也就是说,如果我们对StringBuilder执行任何操作,它都会更新现有的实例值,并且不会创建新的实例。

String 和 StringBuilder 之间的区别