Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# StringBuilder字符串是不可变的吗?_C#_.net_String - Fatal编程技术网

C# StringBuilder字符串是不可变的吗?

C# StringBuilder字符串是不可变的吗?,c#,.net,string,C#,.net,String,StringBuilder被誉为比简单连接字符串更快的字符串操作工具。不管这是不是真的,我都想知道StringBuilder操作的结果以及它们产生的字符串 快速进入Reflector显示StringBuilder.ToString()并不总是返回副本,有时它似乎返回内部字符串的实例。它似乎还使用一些内部函数来操作内部字符串 那么如果我这样做会得到什么呢 string s = "Yo Ho Ho"; StringBuilder sb = new StringBuilder(s); string n

StringBuilder被誉为比简单连接字符串更快的字符串操作工具。不管这是不是真的,我都想知道StringBuilder操作的结果以及它们产生的字符串

快速进入Reflector显示StringBuilder.ToString()并不总是返回副本,有时它似乎返回内部字符串的实例。它似乎还使用一些内部函数来操作内部字符串

那么如果我这样做会得到什么呢

string s = "Yo Ho Ho";
StringBuilder sb = new StringBuilder(s);
string newString = sb.ToString();
sb.Append(" and a bottle of rum.");
string newNewString = sb.ToString();
newString和newNewString是不同的字符串实例还是相同的字符串实例?我试图通过反射器来解决这个问题,但我不是很了解所有的事情

这个代码怎么样

StringBuilder sb = new StringBuilder("Foo\n");
StringReader sr = new StringReader(sb.ToString());
string s = sr.ReadLine();
sb.Append("Bar\n");
s = sr.ReadLine();
最后一条语句是否返回null或“Bar”?如果它返回一个或另一个,这是定义的还是未定义的行为?换句话说,我能依靠它吗


文档在这个主题上非常简洁,我不愿意依赖观察到的行为而不是规范。

在mscorlib之外,任何System.String实例都是不可变的,句号为

StringBuilder在内部对字符串进行了一些有趣的操作,但最终它不会向您返回字符串,然后以代码可见的方式对其进行修改


至于后续调用StringBuilder.ToString()是返回字符串的同一实例,还是返回具有相同值的不同字符串,这取决于实现,您不应该依赖于此行为

newString
newNewString
是不同的字符串实例

尽管
ToString()
返回当前字符串,但它会清除其当前线程变量。这意味着下次追加时,它将在追加之前获取当前字符串的副本


我不完全确定您在第二个问题中的意思,但
s
将为空:如果文件中的最后一个字符是前一行的行终止字符,则该行不会被视为在这些字符和文件结尾之间有一个空行。先前读取的字符串对此没有影响。

这个类的全部目的是使字符串可变,所以它实际上是可变的。我相信(但不确定)只有在没有对这个对象做任何其他操作的情况下,它才会返回进入它的相同字符串。那以后呢

String s_old = "Foo";
StringBuilder sb = new StringBuilder(s_old);
String s_new = sb.ToString();
s_old将与s_new相同,但在任何其他情况下都不会如此

我应该注意到,对于Java编译器,它会自动将多个字符串添加转换为使用StringBuilder(或类似但更快的StringBuffer)类的操作,我会非常惊讶.NET编译器也不会进行这种转换

newString
newNewString
不同的
字符串
实例或 同样的?我一直在想办法 通过反射器,我只是不太清楚 理解一切

它们是不同的
string
实例:
newString
是“
yohoho
”,
newNewString
是“
yohoho和一瓶朗姆酒。
”<代码>字符串是不可变的,当您调用
StringBuilder.ToString()
时,该方法返回一个表示当前状态的不可变
字符串

最后一条语句是否返回
null
或 “
Bar
”?如果它返回一个或另一个 其他,这是定义的还是未定义的 行为?换句话说,我能依靠吗 在上面


它将返回
null
StringReader
正在处理您在构造函数中传递给它的不可变的
string
,因此它不受您对
StringBuilder

所做的任何操作的影响。C编译器不使用StringBuilder进行字符串连接-它使用string.Concat。这意味着在进行任何连接之前,最终的长度是已知的。是的,实验已经证明这是正确的,但是用反射器探测内部并没有给出明显的原因。它似乎在每次调用时都返回对内部字符串的引用,因此我对字符串是否会发生变异感到困惑。@Mystere,StringBuilder的实现一开始有点令人生畏。直到我读了你的问题并开始探索,我才意识到他们做了线程级缓存。我计划今晚晚些时候(或明天)再看一眼。但是您可以信任生成的字符串immutable@JaredPar-虽然这在99.999%的情况下是正确的,但您可以在
mscorlib
之外拥有一个可变字符串。。。只要绳子被固定住。要点:啊。。你向我解释了这个秘密。清除线程变量是导致追加时复制的原因,这是多么简单但不明显。我的第二个问题是可变性问题的一个变体,与StringReader中存储的引用有关。请注意,自从这个问题被提出和回答以来,StringBuilder的实现已经发生了变化。