C# StringBuilder字符串是不可变的吗?
StringBuilder被誉为比简单连接字符串更快的字符串操作工具。不管这是不是真的,我都想知道StringBuilder操作的结果以及它们产生的字符串 快速进入Reflector显示StringBuilder.ToString()并不总是返回副本,有时它似乎返回内部字符串的实例。它似乎还使用一些内部函数来操作内部字符串 那么如果我这样做会得到什么呢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
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的实现已经发生了变化。