String 或 StringBuilder 返回值? [英] String or StringBuilder return values?

查看:130
本文介绍了String 或 StringBuilder 返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If I am building a string using a StringBuilder object in a method, would it make sense to:

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

Return the StringBuilder object, and let the calling code call ToString()?

return sb;

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

OR Return the string by calling ToString() myself.

return sb.ToString();

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

I guess it make a difference if we're returning small, or large strings. What would be appropriate in each case? Thanks in advance.

我不打算进一步修改调用代码中的字符串,但是 Colin Burnett 说得好.

I don't plan on further modifying the string in the calling code, but good point Colin Burnett.

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

Mainly, is it more efficient to return the StringBuilder object, or the string? Would a reference to the string get returned, or a copy?

推荐答案

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

Return the StringBuilder if you're going to further modify the string, otherwise return the string. This is an API question.

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

Regarding efficiency. Since this is a vague/general question without any specifics then I think mutable vs. immutable is more important than performance. Mutability is an API issue of letting your API return modifiable objects. String length is irrelevant to this.

说的.如果您使用反射器查看 StringBuilder.ToString:

That said. If you look at StringBuilder.ToString with Reflector:

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;
}

你可以看到它可能会复制,但如果你用 StringBuilder 修改它,那么它就会复制(这就是我可以告诉 m_currentThread 的一点是因为 Append 检查这个,如果它不匹配,就会复制它当前线程).

You can see it may make a copy but if you modify it with the StringBuilder then it will make a copy then (this is what I can tell the point of m_currentThread is because Append checks this and will copy it if it mismatches the current thread).

我想最后是如果你不修改 StringBuilder 那么你就不会复制字符串并且长度与效率无关(除非你达到了第二个 if).

I guess the end of this is that if you do not modify the StringBuilder then you do not copy the string and length is irrelevant to efficiency (unless you hit that 2nd if).

更新

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

System.String is a class which means it is a reference type (as opposed to value type) so "string foo;" is essentially a pointer. (When you pass a string into a method it passes the pointer, not a copy.) System.String is mutable inside mscorlib but immutable outside of it which is how StringBuilder can manipulate a string.

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

So when ToString() is called it returns its internal string object by reference. At this point you cannot modify it because your code is not in mscorlib. By setting the m_currentThread field to zero then any further operations on the StringBuilder will cause it to copy the string object so it can be modified and not modify the string object it returned in ToString(). Consider this:

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

string foo = sb.ToString();

sb.Append("World");

string bar = sb.ToString();

如果 StringBuilder 没有制作副本,那么最后 foo 将是Hello World",因为 StringBuilder 修改了它.但既然它做了一个副本,那么 foo 仍然只是Hello",而 bar 是Hello World".

If StringBuilder did not make a copy then at the end foo would be "Hello World" because the StringBuilder modified it. But since it did make a copy then foo is still just "Hello " and bar is "Hello World".

这是否澄清了整个返回/引用的事情?

Does that clarify the whole return/reference thing?

这篇关于String 或 StringBuilder 返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆