StringBuilder:如何获取最终字符串?

70

有人告诉我使用 StringBuilder 拼接字符串比较快。我已经更改了我的代码,但是我没有看到可以获取最终构建字符串的属性或方法。

我该如何获取这个字符串?

6个回答

129
您可以使用.ToString()方法从StringBuilder获取一个String

1
它是toString而不是ToString。 - zeus
13
对于 C# 中的 @loki,它是 ToString。 - Abhishek Patel

13
当你说“使用StringBuilder连接字符串更快”的时候,这只有在重复(我再强调一遍-重复)连接到同一个对象时才是正确的。
如果你只是连接两个字符串并立即将结果作为string处理,那么使用StringBuilder就没有意义了。
我刚刚偶然发现Jon Skeet对此进行了很好的写作:
https://jonskeet.uk/csharp/stringbuilder.html 如果你正在使用StringBuilder,那么要获得结果string,只需调用ToString()(毫不奇怪)。

12

使用 StringBuilder 完成处理后,使用 ToString 方法返回最终结果。

来自 MSDN:

using System;
using System.Text;

public sealed class App 
{
    static void Main() 
    {
        // Create a StringBuilder that expects to hold 50 characters.
        // Initialize the StringBuilder with "ABC".
        StringBuilder sb = new StringBuilder("ABC", 50);

        // Append three characters (D, E, and F) to the end of the StringBuilder.
        sb.Append(new char[] { 'D', 'E', 'F' });

        // Append a format string to the end of the StringBuilder.
        sb.AppendFormat("GHI{0}{1}", 'J', 'k');

        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());

        // Insert a string at the beginning of the StringBuilder.
        sb.Insert(0, "Alphabet: ");

        // Replace all lowercase k's with uppercase K's.
        sb.Replace('k', 'K');

        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
    }
}

// This code produces the following output.
//
// 11 chars: ABCDEFGHIJk
// 21 chars: Alphabet: ABCDEFGHIJK

3

我想指出的是,这不一定更快,但肯定会有更好的内存占用。这是因为在.NET中,字符串是不可变的,每次更改字符串都会创建一个新的字符串。


2
关于更快/更好的内存:
我研究了Java中这个问题,我认为.NET也会对此进行智能处理。
String的实现非常出色。
String对象跟踪“长度”和“共享”(与保存字符串的数组的长度无关)。
因此,类似以下代码:
String a = "abc" + "def" + "ghi";

可以由编译器/运行时实现,具体方式如下:

- 将保存“abc”的数组扩展6个附加空间。
- 在abc之后复制def。
- 在def之后复制ghi。
- 给a一个指向"abc"字符串的指针。
- 保持abc长度为3,将a的长度设置为9。
- 在两者中设置共享标志。
由于大多数字符串的生命周期很短,在许多情况下这是非常有效的代码。当您在循环中添加字符串或代码类似于此时,它绝对不是有效的情况。

a = "abc";
a = a + "def";
a += "ghi";

在这种情况下,最好使用StringBuilder结构。
我的观点是,除非你绝对确定自己知道在做什么,并且你确信有必要优化,并且你测试以确保优化后的代码能够通过一个用例,否则你应该谨慎优化,只需尽可能以最可读的方式编写代码,不要试图超越编译器。
我浪费了三天时间处理字符串,缓存/重用字符串生成器并测试速度,然后我查看了字符串源代码,并发现编译器已经比我为我的用例所能做到的更好了。然后我不得不解释我并不真正知道自己在做什么,只是认为自己知道...

1

拼接字符串并不更快 - 正如smaclell所指出的那样,问题在于不可变字符串会强制进行额外的分配和复制现有数据。

"a" + "b" + "c" 用字符串构建器也不会更快,但是使用中间字符串进行重复拼接时,随着拼接数量的增加,速度会越来越快,例如:

x = "a"; x+="b"; x+="c"; ...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接