4

不经常但有时我需要用它String.Trim()来删除字符串的空格。
如果自上次修剪编码以来的时间较长,我会写:

string s = " text ";
s.Trim();

并惊讶为什么 s没有改变。我需要写:

string s = " text ";
s = s.Trim();

为什么是一些以这种(不是很直观)方式设计的字符串方法?字符串有什么特别之处吗?

4

4 回答 4

23

字符串是不可变的。任何字符串操作都会在不改变原始字符串的情况下生成一个新字符串。

来自MSDN

字符串是不可变的——字符串对象的内容在创建对象后不能更改,尽管语法使它看起来好像您可以这样做。

于 2012-04-17T12:00:14.700 回答
7

s.Trim()创建原始字符串的新修剪版本并将其返回,而不是将新版本存储在s. 因此,您要做的就是将修剪后的实例存储在变量中:

  s = s.Trim();

所有字符串方法和扩展方法都遵循这种模式。

字符串是不可变的这一事实与使用此模式的决定无关,而是与字符串如何保存在内存中的事实有关。此方法可以设计为在内存中创建新的修改字符串实例并将变量指向新实例。

还要记住,如果您需要对字符串进行大量修改,最好使用 an StringBuilder,它的行为类似于“可变”字符串,并且执行此类操作更有效。

于 2012-04-17T12:11:47.627 回答
2

正如它在 MSDN 库中所写:

String 对象被称为不可变(只读),因为它的值在创建后无法修改。看似修改 String 对象的方法实际上会返回一个包含修改的新 String 对象。

因为字符串是不可变的,所以重复添加或删除看似单个字符串的字符串操作例程可能会导致显着的性能损失。

请参阅此链接

于 2012-04-17T12:04:11.887 回答
1

除了所有好的答案外,我还觉得原因是 Threadsafty。

让我们说

string s = " any text "; s.Trim();

当您这么说时,没有什么可以阻止其他线程修改 s. 如果修改了相同的字符串,假设另一个线程从 s 中删除 'a',那么 s.Trim() 的结果是什么?

但是当它返回新字符串时,虽然它正在被其他线程修改,但trim可以使本地副本修改它并返回修改后的字符串。

于 2012-04-17T12:59:35.373 回答