String或StringBuilder返回值?

Joh*_*ski 18 c# string stringbuilder return-type return-value

如果我在方法中使用StringBuilder对象构建字符串,那么它是否有意义:

返回StringBuilder对象,让调用代码调用ToString()?

return sb;
Run Code Online (Sandbox Code Playgroud)

或者通过自己调用ToString()返回字符串.

return sb.ToString();
Run Code Online (Sandbox Code Playgroud)

我想如果我们返回小字符串或大字符串会有所不同.在每种情况下适合什么?提前致谢.

编辑:我不打算进一步修改调用代码中的字符串,但好点科林伯内特.

主要是,返回StringBuilder对象或字符串是否更有效?是否会返回对字符串的引用或副本?

Col*_*ett 23

如果您要进一步修改字符串,则返回StringBuilder,否则返回字符串.这是一个API问题.

关于效率.由于这是一个模糊/一般的问题,没有任何细节,我认为可变与不可变比性能更重要.可变性是让API返回可修改对象的API问题.字符串长度与此无关.

那就是说.如果你看一下带有Reflector的StringBuilder.ToString:

public override string ToString()
{
    string stringValue = this.m_StringValue;
    if (this.m_currentThread != Thread.InternalGetCurrentThread())
    {
        return string.InternalCopy(stringValue);
    }
    if ((2 * stringValue.Length) < stringValue.ArrayLength)
    {
        return string.InternalCopy(stringValue);
    }
    stringValue.ClearPostNullChar();
    this.m_currentThread = IntPtr.Zero;
    return stringValue;
}
Run Code Online (Sandbox Code Playgroud)

你可以看到它可以复制,但如果你用StringBuilder修改它然后它会复制一下(这是我可以告诉m_currentThread的意思是因为Append检查这个并且如果它与当前线程不匹配将复制它) .

我想这样做的结果是,如果你不修改StringBuilder,那么就不要复制字符串,长度与效率无关(除非你打到第二个if).

UPDATE

System.String是一个类,这意味着它是一个引用类型(而不是值类型)所以"string foo;" 本质上是一个指针.(当您将字符串传递给方法时,它会传递指针,而不是副本.)System.String在mscorlib中是可变的,但在其外部是不可变的,这是StringBuilder可以操作字符串的方式.

因此,当调用ToString()时,它通过引用返回其内部字符串对象.此时您无法修改它,因为您的代码不在mscorlib中.通过将m_currentThread字段设置为零,然后StringBuilder上的任何进一步操作将使其复制字符串对象,以便可以修改它,不是修改它在ToString()中返回的字符串对象.考虑一下:

StringBuilder sb = new StringBuilder();
sb.Append("Hello ");

string foo = sb.ToString();

sb.Append("World");

string bar = sb.ToString();
Run Code Online (Sandbox Code Playgroud)

如果StringBuilder没有复制,那么最后foo将是"Hello World",因为StringBuilder对其进行了修改.但是因为它确实制作了副本,所以foo仍然只是"Hello"而bar是"Hello World".

这是否澄清了整个退货/参考的事情?


Jos*_*rke 5

我不认为表演应该成为这个问题的一个因素.无论哪种方式,有人会打电话给sb.ToString(),所以你打算去某个地方.

更重要的问题是方法的意图和目的是什么.如果此方法是构建器的一部分,则可能返回字符串构建器.否则我会返回一个字符串.

如果这是公共API的一部分,我会倾向于返回字符串而不是构建器.