web-dev-qa-db-ja.com

StringBuilder:最終的な文字列を取得する方法は?

誰かがStringBuilderで文字列を連結する方が速いと私に言った。コードを変更しましたが、最終的なビルド文字列を取得するためのプロパティまたはメソッドが表示されません。

どうすれば文字列を取得できますか?

57
Mister Dev

.ToString()を使用して、StringからStringBuilderを取得できます。

110

「String BuilderとStringを連結する方が速い」と言うとき、これはrepeatedly(I repeat-繰り返し)同じオブジェクトに連結します。

2つの文字列を連結し、その結果をすぐにstringとして処理する場合、StringBuilderを使用しても意味がありません。

Jon SkeetのNice Nice up on this thisにつまずいた: http://www.yoda.arachsys.com/csharp/stringbuilder.html

StringBuilderを使用している場合、結果のstringを取得するには、ToString()を呼び出すだけです(当然)。

13
Michael Burr

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
10
BlackWasp

必ずしも高速ではないかもしれませんが、それは間違いなくより良いメモリフットプリントを持っています。これは、.NETでは文字列が不変であり、文字列を変更するたびに新しい文字列が作成されるためです。

3
smaclell

メモリの高速化/向上について:

Javaでこの問題を調査しましたが、.NETも同様に賢明だと思います。

Stringの実装は非常に印象的です。

Stringオブジェクトは、「文字列を保持する配列の長さとは無関係に」「長さ」と「共有」を追跡します

のようなもの

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

(コンパイラ/ランタイムにより)以下のように実装できます:

-「abc」を保持する配列を6スペース追加します。
-abcの直後にdefをコピーします
-defの後にghiをコピーします。 
-「abc」文字列へのポインターを
に渡します-abcの長さを3のままにし、aの長さを9 
に設定します-両方に共有フラグを設定します。

ほとんどの文字列は短命なので、多くの場合、これにより非常に効率的なコードが作成されます。絶対に効率的ではない場合は、ループ内の文字列に追加する場合、またはコードが次のような場合です。

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

この場合、StringBuilderコンストラクトを使用するほうがはるかに適切です。

私のポイントは、あなたが何をしているのかを絶対に確信していない限り、最適化するときは常に注意する必要があるということです。可能な限り最も読みやすい方法で、コンパイラを考え抜かないでください。

文字列のソースコードを見る前に、文字列をいじり、文字列ビルダーをキャッシュ/再利用し、速度をテストするのに3日間費やしましたが、コンパイラが既にユースケースよりも優れていることを理解しました。それから私は自分が何をしていたのか本当に本当にわからなかったのか説明しなければなりませんでした。

2
Bill K