17

これらの例の間に違いはありますか?その場合、どちらを使用すればよいですか?

var str1 = "abc" + dynamicString + dynamicString2;

var str2 = String.Format("abc{0}{1}", dynamicString, dynamicString2);

var str3 = new StringBuilder("abc").
    Append(dynamicString).
    Append(dynamicString2).
    ToString();

var str4 = String.Concat("abc", dynamicString, dynamicString2);

同様の質問があります:

  • 演算子についてのみ尋ねる文字列連結の違いで+あり、String.Concatに変換されることは回答にも記載されていません。
  • この質問のように文字列とその出力を連結するための可能な方法の比較ではなく、最良のものを求めている私の質問とは実際には関係のない最良の文字列連結方法は何ですか。

この質問は、それぞれの場合に何が起こるか、それらの例の実際の出力はどうなるかについて尋ねています。それらの違いは何ですか?その場合、どこで使用すればよいですか?

4

10 に答える 10

16

非常に多くの(100+)文字列または非常に大きな(長さ> 10000)文字列を使用しない限り、唯一の基準は読みやすさです。

このサイズの問題については、を使用して+ください。その+オーバーロードは、読みやすくするために文字列クラスに追加されました。

string.Format()より複雑な構成や、置換またはフォーマットが必要な場合に使用します。

StringBuilder多数のピース(数百以上)または非常に大きなピース(長さ>> 1000)を組み合わせる場合に使用します。StringBuilderには読みやすさの機能はなく、パフォーマンスのためだけにあります。

于 2010-06-23T15:01:14.880 に答える
8

すべての回答から情報を収集すると、次のように動作することが判明しました。

+演算子は と同じです。String.Concatこれは、ループ外の小さな連結で使用でき、小さなタスクで使用できます。

コンパイル時に、+演算子が静的な場合は単一の文字列を生成しますが、静的な場合でもString.Concat式を生成しstr = str1 + str2;ます。

String.Formatパラメータの検証を行い、パラメータの長さで内部をインスタンス化するStringBuilder..ことを除いて、(例 3)と同じです。String.FormatStringBuilder

String.Formatフォーマット文字列が必要な場合、および単純な文字列を連結するために使用する必要があります。

StringBuilder大きな文字列を連結する必要がある場合やループで使用する必要があります。

于 2010-06-23T18:06:03.087 に答える
5

シナリオで + 演算子を使用します。

String.Format() メソッドは、文字列に保持する変数データと静的データが混在している場合にのみ使用します。例えば:

string result=String.Format(
    "Today {0} scored {1} {2} and {3} points against {4}",..);

//looks nicer than
string result = "Today " + playerName + " scored " + goalCount + " " + 
    scoreType + " and " + pointCount + " against " + opposingTeam;

既に 3 つの文字列リテラルを扱っているため、StringBuilder を使用する意味がわかりません。

個人的には、文字列配列を扱う場合にのみ Concat を使用します。

于 2010-06-23T16:03:05.923 に答える
2

私の経験則ではString.Format、比較的少量の連結 (<100) をStringBuilder行う場合、および連結が大きくなるか、大きくなる可能性がある場合に使用します。String.Join配列があり、書式設定が必要ない場合に使用します。

列挙可能なコレクションがある場合は、LINQ で Aggregate 関数を使用することもできます。 http://msdn.microsoft.com/en-us/library/bb548651.aspx

于 2010-06-23T15:34:55.060 に答える
1

@ Jerod Houghtellingアンサー

実際、String.Format は舞台裏で StringBuilder を使用します (必要に応じて String.Format で Reflecton を使用します)。

私は一般的に次の答えに同意します

于 2010-06-23T15:41:41.637 に答える
1

@ザンダー。私はあなたを信じています。ただし、私のコードは、sb が string.format よりも高速であることを示しています。

これを打ちます:

Stopwatch sw = new Stopwatch();
sw.Start();

for (int i = 0; i < 10000; i++)
{
    string r = string.Format("ABC{0}{1}{2}", i, i-10, 
        "dasdkadlkdjakdljadlkjdlkadjalkdj");
}

sw.Stop();
Console.WriteLine("string.format: " + sw.ElapsedTicks);

sw.Reset();
sw.Start();
for (int i = 0; i < 10000; i++)
{
    StringBuilder sb = new StringBuilder();
    string r = sb.AppendFormat("ABC{0}{1}{2}", i, i - 10,
        "dasdkadlkdjakdljadlkjdlkadjalkdj").ToString();
}

sw.Stop();
Console.WriteLine("AppendFormat: " + sw.ElapsedTicks);
于 2010-06-23T17:11:10.597 に答える
0

文字列は通常のオブジェクトのようには動作しないことに注意してください。次のコードを使用します。

string s3 = "Hello ";
string s3 += "World";

このコードは、ヒープに新しい文字列を作成し、「Hello」を配置します。スタック上の文字列オブジェクトは、(通常のオブジェクトと同様に) それを指します。

行 2 は、ヒープ「Hello World」に 2 番目の文字列を作成し、スタック上のオブジェクトをその文字列にポイントします。初期スタック割り当ては、ガベージ コレクターが呼び出されるまでそのままです。

そのため....ガベージコレクターが呼び出される前にこれらの呼び出しが大量にある場合、多くのメモリを浪費している可能性があります。

于 2010-08-09T08:31:38.080 に答える
0

文字列は不変であり、変更されないことを理解することが重要です。したがって、文字列を変更、追加、修正するときはいつでも、メモリ内に文字列の新しい「バージョン」を作成し、古いバージョンをガベージ コレクションに渡します。だから、このようなもの:

string output = firstName.ToUpper().ToLower() + "test";

これは、(出力用の) 文字列を作成し、メモリ内に他の 3 つの文字列を作成します (1 つは ToUpper()、ToLower() の出力用、もう 1 つは "test" の連結用)。

したがって、StringBuilder または string.Format を使用しない限り、他の操作を行うと、メモリ内に文字列の余分なインスタンスが作成されます。もちろん、これはループ内の問題であり、数百または数千の余分な文字列が発生する可能性があります。それが役立つことを願っています

于 2010-06-24T05:19:54.257 に答える
0

誰もこの方法を知らないことがわかります:

string Color = "red";
Console.WriteLine($"The apple is {Color}");
于 2021-09-25T11:05:19.523 に答える
-1
var str3 = new StringBuilder
    .AppendFormat("abc{0}{1}", dynamicString, dynamicString2).ToString(); 

上記のコードは最速です。あなたがそれを速くしたい場合に使用してください。気にしない場合は、他のものを使用してください。

于 2010-06-23T16:43:01.697 に答える