C# StringBuilderの使い方完全ガイド|文字列結合との違い・高速化・実例を初心者向けに解説

はじめに

C#で文字列を扱うとき、多くの初心者が最初に使うのはstring+演算子による文字列結合です。たとえば、名前やメッセージをつなげる程度であれば、stringだけでも十分にわかりやすく書けます。

しかし、ループの中で何百回、何千回も文字列を追加したり、CSV、HTML、ログ、SQLのような長い文字列を段階的に組み立てたりする場合、stringの結合だけでは効率が悪くなることがあります。そこで活躍するのがStringBuilderです。

この記事では、C#のStringBuilderの基本的な使い方から、stringとの違い、文字列結合を高速化できる理由、実践的なサンプルコード、よくある注意点まで初心者向けにわかりやすく解説します。

1. C#のStringBuilderとは?初心者向けに基本を解説

1-1. StringBuilderは可変長の文字列を効率よく扱うクラス

StringBuilderは、文字列を効率よく追加・変更・削除するためのクラスです。C#ではSystem.Text.StringBuilderとして用意されています。

通常のstringでも文字列を扱えますが、何度も文字列を結合する処理では、新しい文字列オブジェクトが何度も作られるため、処理速度やメモリ使用量に影響することがあります。

一方、StringBuilderは内部に変更可能な文字列バッファを持っており、その内容を直接変更しながら文字列を組み立てられます。そのため、大量の文字列を連結する場面でよく使われます。

1-2. stringとの違い:stringは不変、StringBuilderは変更可能

C#のstringは「不変」です。不変とは、一度作成された文字列の内容を変更できないという意味です。

たとえば次のコードを見てみましょう。

C#
string text = "Hello";
text += " World";

このコードでは、textの中身が直接変更されているように見えます。しかし実際には、"Hello"という文字列に" World"を追加した新しい文字列"Hello World"が作られ、textがその新しい文字列を参照するようになります。

一方、StringBuilderは内容を変更できます。

C#
var sb = new StringBuilder();
sb.Append("Hello");
sb.Append(" World");

この場合、StringBuilderの内部バッファに対して文字列が追加されます。何度も追加しても、毎回新しいstringを作り直すわけではないため、効率的です。

1-3. StringBuilderを使うにはSystem.Textをusingする

StringBuilderを使うには、基本的にファイルの先頭に次のusingを追加します。

C#
using System.Text;

そのうえで、次のようにインスタンスを作成します。

C#
StringBuilder sb = new StringBuilder();

C#では型推論を使って、次のようにも書けます。

C#
var sb = new StringBuilder();

初心者のうちは、StringBuilderを使うときはusing System.Text;が必要だと覚えておきましょう。

1-4. StringBuilderがよく使われる場面

StringBuilderは、次のような場面でよく使われます。

C#
// 大量の文字列をループで連結する
// CSVデータを作成する
// HTMLのような複数行の文字列を組み立てる
// ログメッセージを動的に作成する
// 条件に応じて文字列を追加する

特に、ループの中で何度も文字列を追加する処理では、StringBuilderの効果が出やすいです。

2. C#でStringBuilderを使う基本手順

2-1. StringBuilderのインスタンスを作成する

まずはStringBuilderのインスタンスを作成します。

C#
using System.Text;

var sb = new StringBuilder();

このsbに対して、文字列を追加したり、挿入したり、置換したりしていきます。

初期文字列を指定して作成することもできます。

C#
var sb = new StringBuilder("最初の文字列");

また、あらかじめ長い文字列になることがわかっている場合は、初期容量を指定できます。

C#
var sb = new StringBuilder(1024);

2-2. Appendで文字列を追加する

Appendは、StringBuilderの末尾に文字列を追加するメソッドです。

C#
var sb = new StringBuilder();

sb.Append("Hello");
sb.Append(" ");
sb.Append("World");

この時点で、sbの内容はHello Worldになります。

Appendは文字列だけでなく、数値や真偽値なども追加できます。

C#
sb.Append(100);
sb.Append(true);

2-3. AppendLineで改行付きの文字列を追加する

AppendLineは、文字列を追加したあとに改行も追加するメソッドです。

C#
var sb = new StringBuilder();

sb.AppendLine("1行目");
sb.AppendLine("2行目");
sb.AppendLine("3行目");

複数行の文章やログ、CSV、HTMLなどを作るときに便利です。

文字列を指定せずに、改行だけを追加することもできます。

C#
sb.AppendLine();

2-4. ToStringで最終的な文字列に変換する

StringBuilderで組み立てた内容を最終的にstringとして使うには、ToString()を呼び出します。

C#
string result = sb.ToString();

Console.WriteLineに直接渡す場合でも、自動的に文字列として扱われることはありますが、変数に代入したり、メソッドに渡したりする場合はToString()を使うのが基本です。

C#
Console.WriteLine(sb.ToString());

2-5. 基本コード例で流れを確認する

ここまでの基本的な流れを、1つのコードで確認してみましょう。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
var sb = new StringBuilder();

sb.Append("こんにちは、");
sb.Append("C#の");
sb.Append("StringBuilder");
sb.AppendLine("です。");

sb.AppendLine("文字列を効率よく組み立てられます。");

string result = sb.ToString();

Console.WriteLine(result);
}
}

実行結果は次のようになります。

こんにちは、C#のStringBuilderです。
文字列を効率よく組み立てられます。

StringBuilderは、作成、追加、変換という流れで使うのが基本です。

3. StringBuilderの主要メソッド一覧と使い方

3-1. Append:末尾に文字列を追加する

Appendは最もよく使うメソッドです。現在の内容の末尾に文字列を追加します。

C#
var sb = new StringBuilder();

sb.Append("C#");
sb.Append(" ");
sb.Append("StringBuilder");

Console.WriteLine(sb.ToString());

出力結果は次のとおりです。

C# StringBuilder

文字列を少しずつ組み立てたいときの基本メソッドです。

3-2. AppendLine:改行を含めて追加する

AppendLineは、文字列の追加と改行を同時に行います。

C#
var sb = new StringBuilder();

sb.AppendLine("名前: 山田太郎");
sb.AppendLine("年齢: 30");
sb.AppendLine("職業: エンジニア");

Console.WriteLine(sb.ToString());

出力結果は次のようになります。

名前: 山田太郎
年齢: 30
職業: エンジニア

複数行の文字列を作る場合は、AppendよりもAppendLineを使ったほうが読みやすくなります。

3-3. Insert:指定位置に文字列を挿入する

Insertは、指定した位置に文字列を挿入するメソッドです。

C#
var sb = new StringBuilder("C# Builder");

sb.Insert(3, "String");

Console.WriteLine(sb.ToString());

出力結果は次のとおりです。

C# StringBuilder

Insert(3, "String")は、インデックス3の位置にStringを挿入するという意味です。

3-4. Replace:文字列を置換する

Replaceは、指定した文字列を別の文字列に置き換えるメソッドです。

C#
var sb = new StringBuilder("C# StringBuilder is difficult.");

sb.Replace("difficult", "useful");

Console.WriteLine(sb.ToString());

出力結果は次のようになります。

C# StringBuilder is useful.

テンプレート文字列の一部を置換したい場合などに便利です。

3-5. Remove:指定範囲の文字列を削除する

Removeは、指定した位置から指定した文字数分の文字列を削除します。

C#
var sb = new StringBuilder("C# Java StringBuilder");

sb.Remove(3, 5);

Console.WriteLine(sb.ToString());

出力結果は次のようになります。

C# StringBuilder

Remove(3, 5)は、インデックス3から5文字分を削除するという意味です。

3-6. Clear:内容を空にする

Clearは、StringBuilderの内容を空にするメソッドです。

C#
var sb = new StringBuilder();

sb.Append("古い内容");
sb.Clear();
sb.Append("新しい内容");

Console.WriteLine(sb.ToString());

出力結果は次のとおりです。

新しい内容

同じStringBuilderを再利用したい場合に便利です。

3-7. AppendFormat:書式付き文字列を追加する

AppendFormatは、書式付きの文字列を追加するメソッドです。

C#
var sb = new StringBuilder();

string name = "佐藤";
int score = 95;

sb.AppendFormat("{0}さんの点数は{1}点です。", name, score);

Console.WriteLine(sb.ToString());

出力結果は次のようになります。

佐藤さんの点数は95点です。

最近のC#では文字列補間を使うことも多いですが、書式を細かく指定したい場合にはAppendFormatも役立ちます。

C#
var price = 1234;

sb.AppendFormat("価格: {0:N0}円", price);

4. StringBuilderと文字列結合の違い

4-1. +演算子による文字列結合の特徴

C#では、+演算子を使って文字列を結合できます。

C#
string message = "Hello" + " " + "World";

この書き方はシンプルで読みやすいため、少ない回数の結合では非常に便利です。

たとえば次のようなコードなら、無理にStringBuilderを使う必要はありません。

C#
string name = "田中";
string message = "こんにちは、" + name + "さん";

ただし、ループの中で何度も+を使って文字列を追加すると、毎回新しい文字列が作られるため、処理が非効率になることがあります。

4-2. string.Concatとの違い

string.Concatは、複数の文字列を結合するメソッドです。

C#
string result = string.Concat("C#", " ", "StringBuilder");

単純に複数の文字列を一度に結合する場合は、string.Concatでも十分です。

一方、StringBuilderは、後から何度も追加・変更していく処理に向いています。

C#
var sb = new StringBuilder();
sb.Append("C#");
sb.Append(" ");
sb.Append("StringBuilder");

一度だけ結合するならstring.Concat、段階的に何度も組み立てるならStringBuilderと考えるとわかりやすいです。

4-3. 文字列補間との違い

文字列補間は、変数を文字列の中に埋め込める便利な書き方です。

C#
string name = "鈴木";
int age = 25;

string message = $"{name}さんは{age}歳です。";

短いメッセージを作る場合は、文字列補間が最も読みやすいことが多いです。

ただし、ループ内で文字列補間を何度も使って結合する場合は注意が必要です。

C#
string result = "";

for (int i = 0; i < 10000; i++)
{
result += $"{i},";
}

このような処理では、StringBuilderを使ったほうが効率的です。

C#
var sb = new StringBuilder();

for (int i = 0; i < 10000; i++)
{
sb.Append(i);
sb.Append(",");
}

string result = sb.ToString();

4-4. ループ内の大量結合でStringBuilderが有利な理由

stringは不変なので、文字列を追加するたびに新しい文字列が作られます。

たとえば次のような処理では、ループのたびに新しい文字列が生成されます。

C#
string text = "";

for (int i = 0; i < 10000; i++)
{
text += i.ToString();
}

回数が少なければ問題になりにくいですが、回数が多くなるほどメモリ確保やコピーの負担が大きくなります。

StringBuilderを使うと、内部のバッファに対して文字列を追加していくため、無駄な文字列生成を減らせます。

C#
var sb = new StringBuilder();

for (int i = 0; i < 10000; i++)
{
sb.Append(i);
}

string text = sb.ToString();

このため、ループ内で大量に文字列を結合する処理ではStringBuilderが有利です。

4-5. 少ない結合ならstringのほうが読みやすいケースもある

StringBuilderは便利ですが、常に使うべきというわけではありません。

たとえば、次のような短い文字列であれば、文字列補間のほうが読みやすいです。

C#
string name = "高橋";
int count = 3;

string message = $"{name}さんは商品を{count}個購入しました。";

これを無理にStringBuilderで書くと、かえって読みにくくなります。

C#
var sb = new StringBuilder();
sb.Append(name);
sb.Append("さんは商品を");
sb.Append(count);
sb.Append("個購入しました。");

string message = sb.ToString();

少ない結合ならstringや文字列補間、多い結合ならStringBuilderという使い分けが大切です。

5. StringBuilderで文字列結合を高速化する実例

5-1. for文で大量の文字列を連結するサンプル

大量の文字列を連結する代表例です。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
var sb = new StringBuilder();

for (int i = 1; i <= 10000; i++)
{
sb.Append("No.");
sb.Append(i);
sb.AppendLine();
}

string result = sb.ToString();

Console.WriteLine(result);
}
}

このコードでは、No.1からNo.10000までの文字列を作成しています。

+演算子で何度も結合するより、StringBuilderを使ったほうが効率よく処理できます。

5-2. CSV形式の文字列を作成するサンプル

CSV形式のデータを作るときにもStringBuilderはよく使われます。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
var sb = new StringBuilder();

sb.AppendLine("Id,Name,Age");
sb.AppendLine("1,Yamada,30");
sb.AppendLine("2,Sato,25");
sb.AppendLine("3,Suzuki,28");

string csv = sb.ToString();

Console.WriteLine(csv);
}
}

出力結果は次のようになります。

Id,Name,Age
1,Yamada,30
2,Sato,25
3,Suzuki,28

複数行のデータを作る場合は、AppendLineを使うと読みやすくなります。

5-3. HTMLやSQLのような長い文字列を組み立てるサンプル

HTMLのように複数行で構成される文字列も、StringBuilderで組み立てるとわかりやすくなります。

C#
var title = "商品一覧";

var sb = new StringBuilder();

sb.AppendLine("<html>");
sb.AppendLine("<head>");
sb.AppendLine($"<title>{title}</title>");
sb.AppendLine("</head>");
sb.AppendLine("<body>");
sb.AppendLine("<h1>商品一覧</h1>");
sb.AppendLine("<ul>");
sb.AppendLine("<li>りんご</li>");
sb.AppendLine("<li>みかん</li>");
sb.AppendLine("<li>バナナ</li>");
sb.AppendLine("</ul>");
sb.AppendLine("</body>");
sb.AppendLine("</html>");

string html = sb.ToString();

Console.WriteLine(html);

SQL文を組み立てる場合にもStringBuilderは使えます。

C#
var sb = new StringBuilder();

sb.AppendLine("SELECT");
sb.AppendLine(" Id,");
sb.AppendLine(" Name,");
sb.AppendLine(" Age");
sb.AppendLine("FROM Users");
sb.AppendLine("WHERE IsActive = 1");

string sql = sb.ToString();

ただし、ユーザー入力を含むSQLを文字列結合で作るのはSQLインジェクションの危険があります。実際のアプリケーションでは、パラメーター化クエリを使うようにしましょう。

5-4. ログメッセージを動的に作成するサンプル

条件に応じてログメッセージを組み立てる場合にも便利です。

C#
var userName = "yamada";
var success = true;
var sb = new StringBuilder();

sb.Append("[Login] ");
sb.Append("User=");
sb.Append(userName);
sb.Append(", Result=");

if (success)
{
sb.Append("Success");
}
else
{
sb.Append("Failed");
}

string log = sb.ToString();

Console.WriteLine(log);

出力結果は次のとおりです。

[Login] User=yamada, Result=Success

条件分岐によって追加する文字列が変わる場合、StringBuilderを使うと柔軟に組み立てられます。

5-5. string結合とStringBuilderの処理速度を比較する

簡単な速度比較コードを見てみましょう。

C#
using System;
using System.Diagnostics;
using System.Text;

class Program
{
static void Main()
{
const int count = 50000;

var sw1 = Stopwatch.StartNew();

string text = "";
for (int i = 0; i < count; i++)
{
text += i;
}

sw1.Stop();

var sw2 = Stopwatch.StartNew();

var sb = new StringBuilder();
for (int i = 0; i < count; i++)
{
sb.Append(i);
}

string result = sb.ToString();

sw2.Stop();

Console.WriteLine($"string結合: {sw1.ElapsedMilliseconds}ms");
Console.WriteLine($"StringBuilder: {sw2.ElapsedMilliseconds}ms");
}
}

実行環境によって結果は変わりますが、大量の文字列結合ではStringBuilderのほうが速くなる傾向があります。

ただし、少ない回数の結合では差がほとんど出ないこともあります。速度だけでなく、コードの読みやすさも考えて使い分けましょう。

6. StringBuilderを使うべきケース・使わないほうがよいケース

6-1. ループで何度も文字列を追加する場合

StringBuilderを使うべき代表的なケースは、ループで何度も文字列を追加する場合です。

C#
var sb = new StringBuilder();

foreach (var item in items)
{
sb.AppendLine(item);
}

string result = sb.ToString();

要素数が多いリストや配列を文字列に変換する場合は、StringBuilderが向いています。

6-2. 長い文字列を段階的に組み立てる場合

HTML、CSV、ログ、レポート本文など、長い文字列を少しずつ作る場合にもStringBuilderが便利です。

C#
var sb = new StringBuilder();

sb.AppendLine("レポート");
sb.AppendLine("==========");
sb.AppendLine("売上: 100000円");
sb.AppendLine("利益: 30000円");
sb.AppendLine("==========");

string report = sb.ToString();

複数行の文字列を段階的に作る場合は、AppendLineを組み合わせると読みやすくなります。

6-3. 条件分岐で追加内容が変わる場合

条件によって追加する内容が変わる場合にもStringBuilderは便利です。

C#
var sb = new StringBuilder();

sb.Append("検索条件: ");

if (!string.IsNullOrEmpty(keyword))
{
sb.Append("キーワード=");
sb.Append(keyword);
sb.Append(" ");
}

if (minPrice > 0)
{
sb.Append("最低価格=");
sb.Append(minPrice);
sb.Append(" ");
}

string conditionText = sb.ToString();

条件が増えるほど、StringBuilderで段階的に組み立てるメリットが大きくなります。

6-4. 単純な1〜数回の結合では不要な場合

次のような単純な結合では、StringBuilderを使う必要はほとんどありません。

C#
string firstName = "Taro";
string lastName = "Yamada";

string fullName = firstName + " " + lastName;

この程度であれば、文字列補間を使ったほうが読みやすいです。

C#
string fullName = $"{firstName} {lastName}";

StringBuilderは、大量の結合や段階的な組み立てが必要なときに使うのが基本です。

6-5. 可読性を優先すべき場面

プログラムでは、処理速度だけでなく可読性も重要です。

たとえば、次のようなメッセージなら文字列補間のほうが自然です。

C#
string message = $"{userName}さん、ようこそ。現在のポイントは{point}です。";

これをStringBuilderで書くと、行数が増えて読みにくくなる場合があります。

C#
var sb = new StringBuilder();
sb.Append(userName);
sb.Append("さん、ようこそ。現在のポイントは");
sb.Append(point);
sb.Append("です。");

string message = sb.ToString();

コードの読みやすさを損なう場合は、無理にStringBuilderを使わないようにしましょう。

7. StringBuilderを効率よく使うコツ

7-1. 初期容量を指定してメモリ再確保を減らす

StringBuilderは内部に文字列を格納するための容量を持っています。文字列が増えて容量が足りなくなると、内部的に容量を増やします。

大量の文字列を追加することが事前にわかっている場合は、初期容量を指定すると効率がよくなる場合があります。

C#
var sb = new StringBuilder(10000);

初期容量を指定することで、内部バッファの再確保を減らせる可能性があります。

ただし、必要以上に大きな容量を指定するとメモリを無駄に使うこともあるため、目安がある場合に使いましょう。

7-2. Clearで再利用する

同じStringBuilderを何度も使いたい場合は、Clearで内容を空にして再利用できます。

C#
var sb = new StringBuilder();

sb.Append("1回目の内容");
Console.WriteLine(sb.ToString());

sb.Clear();

sb.Append("2回目の内容");
Console.WriteLine(sb.ToString());

短時間に何度も文字列を組み立てる処理では、Clearを使って再利用すると便利です。

ただし、再利用しすぎてコードの見通しが悪くなる場合は、新しく作成したほうがわかりやすいこともあります。

7-3. AppendLineとEnvironment.NewLineを使い分ける

改行を追加したい場合は、基本的にAppendLineを使うと便利です。

C#
sb.AppendLine("1行目");
sb.AppendLine("2行目");

一方、文字列の途中に明示的に改行を入れたい場合は、Environment.NewLineを使うこともできます。

C#
sb.Append("1行目");
sb.Append(Environment.NewLine);
sb.Append("2行目");

通常はAppendLineで十分ですが、細かく改行位置を制御したい場合にはEnvironment.NewLineを使うとよいでしょう。

7-4. 最後に必ずToStringする

StringBuilderは文字列を組み立てるためのクラスですが、最終的にstringとして使う場合はToString()が必要です。

C#
var sb = new StringBuilder();

sb.Append("C#");
sb.Append(" StringBuilder");

string result = sb.ToString();

メソッドの戻り値として文字列を返す場合も、ToString()を使います。

C#
static string CreateMessage(string name)
{
var sb = new StringBuilder();

sb.Append("こんにちは、");
sb.Append(name);
sb.Append("さん");

return sb.ToString();
}

7-5. 文字列補間とAppendを組み合わせるときの注意点

StringBuilderでは、Appendの中で文字列補間を使うこともできます。

C#
sb.Append($"{name}さんの点数は{score}点です。");

この書き方は読みやすいですが、文字列補間によって一度stringが作られてからAppendされます。

大量ループで少しでも効率を意識するなら、次のように分けて追加する書き方も検討できます。

C#
sb.Append(name);
sb.Append("さんの点数は");
sb.Append(score);
sb.Append("点です。");

とはいえ、実務では読みやすさも大切です。極端な大量処理でなければ、可読性を優先して文字列補間を使っても問題ないケースは多いです。

8. StringBuilderでよくあるエラーと注意点

8-1. using System.Textを書き忘れる

StringBuilderを使うときによくあるミスが、using System.Text;を書き忘れることです。

C#
using System.Text;

これを書かずにStringBuilderを使うと、環境によっては名前が見つからないというエラーになります。

C#
var sb = new StringBuilder();

エラーが出た場合は、まずusing System.Text;があるか確認しましょう。

8-2. ToStringしないまま使おうとする

StringBuilderで作った内容をstringとして扱うには、基本的にToString()が必要です。

C#
var sb = new StringBuilder();
sb.Append("Hello");

string text = sb.ToString();

次のように、StringBuilderそのものをstring型の変数に代入することはできません。

C#
// エラー
// string text = sb;

StringBuilderstringは別の型であることを覚えておきましょう。

8-3. nullをAppendしたときの挙動

Appendnullを渡した場合、例外は発生せず、何も追加されません。

C#
var sb = new StringBuilder();

string value = null;

sb.Append("A");
sb.Append(value);
sb.Append("B");

Console.WriteLine(sb.ToString());

出力結果は次のようになります。

AB

nullという文字を追加したい場合は、明示的に文字列として指定します。

C#
sb.Append("null");

また、nullを別の文字に置き換えたい場合は、null合体演算子を使うと便利です。

C#
sb.Append(value ?? "(なし)");

8-4. 不要なStringBuilder化でコードが読みにくくなる

StringBuilderは便利ですが、短い文字列まで何でもStringBuilderで書くと、コードが読みにくくなることがあります。

C#
var sb = new StringBuilder();
sb.Append("こんにちは、");
sb.Append(name);
sb.Append("さん");

string message = sb.ToString();

この程度なら、次のように文字列補間で書いたほうが自然です。

C#
string message = $"こんにちは、{name}さん";

StringBuilderは、必要な場面で使うことが大切です。

8-5. スレッドセーフではない点に注意する

StringBuilderは、複数のスレッドから同時に安全に操作できるようには設計されていません。

複数スレッドから同じStringBuilderを同時に操作すると、意図しない結果になる可能性があります。

C#
// 複数スレッドで同じStringBuilderを同時に変更するのは注意が必要
var sb = new StringBuilder();

通常の単一スレッドの処理では問題ありませんが、並列処理や非同期処理で共有する場合は、ロックを使うか、スレッドごとに別のStringBuilderを使うなどの対策が必要です。

9. StringBuilderの実践サンプルコード集

9-1. 複数行の文章を作成する

複数行のメッセージを作成する例です。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
var sb = new StringBuilder();

sb.AppendLine("お知らせ");
sb.AppendLine("----------");
sb.AppendLine("明日はシステムメンテナンスを行います。");
sb.AppendLine("作業時間: 10:00〜12:00");
sb.AppendLine("ご協力をお願いいたします。");

string message = sb.ToString();

Console.WriteLine(message);
}
}

AppendLineを使うことで、改行を含む文章を簡単に作成できます。

9-2. 配列やリストの要素を連結する

配列の要素を1行ずつ連結する例です。

C#
string[] fruits = { "Apple", "Orange", "Banana" };

var sb = new StringBuilder();

foreach (var fruit in fruits)
{
sb.AppendLine(fruit);
}

string result = sb.ToString();

Console.WriteLine(result);

出力結果は次のようになります。

Apple
Orange
Banana

リストでも同じように使えます。

C#
var names = new List<string> { "Yamada", "Sato", "Suzuki" };

var sb = new StringBuilder();

foreach (var name in names)
{
sb.AppendLine(name);
}

Console.WriteLine(sb.ToString());

9-3. 区切り文字付きで文字列を組み立てる

カンマ区切りの文字列を作る例です。

C#
string[] names = { "Yamada", "Sato", "Suzuki" };

var sb = new StringBuilder();

for (int i = 0; i < names.Length; i++)
{
if (i > 0)
{
sb.Append(", ");
}

sb.Append(names[i]);
}

string result = sb.ToString();

Console.WriteLine(result);

出力結果は次のとおりです。

Yamada, Sato, Suzuki

ただし、単純に区切り文字で連結するだけなら、string.Joinを使ったほうが簡単です。

C#
string result = string.Join(", ", names);

複雑な条件付きで要素を追加する場合はStringBuilder、単純な区切り連結ならstring.Joinが向いています。

9-4. 表形式データを文字列に変換する

表形式のデータを文字列として組み立てる例です。

C#
var users = new[]
{
new { Id = 1, Name = "Yamada", Age = 30 },
new { Id = 2, Name = "Sato", Age = 25 },
new { Id = 3, Name = "Suzuki", Age = 28 }
};

var sb = new StringBuilder();

sb.AppendLine("ID\tName\tAge");
sb.AppendLine("---------------------");

foreach (var user in users)
{
sb.Append(user.Id);
sb.Append("\t");
sb.Append(user.Name);
sb.Append("\t");
sb.AppendLine(user.Age.ToString());
}

string table = sb.ToString();

Console.WriteLine(table);

出力結果は次のようになります。

ID      Name    Age
---------------------
1 Yamada 30
2 Sato 25
3 Suzuki 28

レポートやデバッグ用の出力を作るときに便利です。

9-5. 条件に応じて文字列を追加する

条件によって内容が変わるメッセージを作成する例です。

C#
string userName = "Yamada";
bool isPremium = true;
int point = 1200;

var sb = new StringBuilder();

sb.Append(userName);
sb.Append("さん、ようこそ。");

if (isPremium)
{
sb.Append("プレミアム会員です。");
}

if (point > 0)
{
sb.Append("現在のポイントは");
sb.Append(point);
sb.Append("です。");
}

string message = sb.ToString();

Console.WriteLine(message);

出力結果は次のとおりです。

Yamadaさん、ようこそ。プレミアム会員です。現在のポイントは1200です。

条件が複数ある場合でも、StringBuilderを使えば段階的に文字列を組み立てられます。

10. C# StringBuilderに関するよくある質問

10-1. StringBuilderはいつ使うべき?

StringBuilderは、ループで何度も文字列を追加する場合や、長い文字列を段階的に組み立てる場合に使うのがおすすめです。

たとえば、CSV、HTML、ログ、レポート、複数行のメッセージなどを作る場面に向いています。

一方、1回から数回程度の単純な結合であれば、stringや文字列補間のほうが読みやすいです。

C#
string message = $"{name}さん、こんにちは";

大量結合ならStringBuilder、短い文字列ならstringや文字列補間と覚えておくとよいでしょう。

10-2. StringBuilderとstring.Joinはどちらを使うべき?

配列やリストの要素を区切り文字で単純に連結するだけなら、string.Joinのほうが簡単です。

C#
string[] names = { "Yamada", "Sato", "Suzuki" };

string result = string.Join(", ", names);

一方、条件によって要素を追加したり、途中で別の文字列を挿入したり、複雑な形式で組み立てたりする場合はStringBuilderが向いています。

C#
var sb = new StringBuilder();

foreach (var name in names)
{
if (name.StartsWith("S"))
{
sb.AppendLine(name);
}
}

単純な連結ならstring.Join、複雑な組み立てならStringBuilderを使いましょう。

10-3. StringBuilderは本当に高速?

StringBuilderは、文字列を何度も追加する処理では高速になることが多いです。

特に、ループ内で大量に文字列を結合する場合、string+演算子よりも効率的です。

ただし、常にStringBuilderが最速というわけではありません。結合回数が少ない場合や、短い文字列を作るだけの場合は、stringや文字列補間のほうがシンプルで十分です。

パフォーマンスが重要な処理では、実際のデータ量と実行環境で計測して判断することが大切です。

10-4. AppendとAppendLineの違いは?

Appendは、文字列をそのまま末尾に追加します。

C#
sb.Append("Hello");
sb.Append("World");

この場合、結果は次のようになります。

HelloWorld

AppendLineは、文字列を追加したあとに改行も追加します。

C#
sb.AppendLine("Hello");
sb.AppendLine("World");

この場合、結果は次のようになります。

Hello
World

改行が必要ない場合はAppend、行単位で追加したい場合はAppendLineを使いましょう。

10-5. StringBuilderの中身を空にする方法は?

StringBuilderの中身を空にするには、Clear()を使います。

C#
var sb = new StringBuilder();

sb.Append("古い内容");

sb.Clear();

sb.Append("新しい内容");

Console.WriteLine(sb.ToString());

出力結果は次のとおりです。

新しい内容

Clearを使うと、同じStringBuilderインスタンスを再利用できます。

まとめ

C#のStringBuilderは、文字列を効率よく追加・変更・削除できる便利なクラスです。通常のstringは不変であり、文字列を結合するたびに新しい文字列が作られます。そのため、ループ内で大量に文字列を連結するような処理では、StringBuilderを使うことで処理速度やメモリ効率を改善できる場合があります。

基本的な使い方は、StringBuilderのインスタンスを作成し、AppendAppendLineで文字列を追加し、最後にToString()stringに変換するという流れです。

C#
var sb = new StringBuilder();

sb.Append("C#");
sb.Append(" ");
sb.Append("StringBuilder");

string result = sb.ToString();

AppendAppendLineInsertReplaceRemoveClearAppendFormatなどのメソッドを覚えておくと、さまざまな文字列処理に対応できます。

ただし、すべての文字列結合にStringBuilderを使えばよいわけではありません。短い文字列や少ない回数の結合であれば、string+演算子、文字列補間、string.Joinのほうが読みやすい場合もあります。

重要なのは、目的に応じて使い分けることです。大量の文字列を段階的に組み立てるならStringBuilder、単純で短い文字列ならstringや文字列補間を使うと、読みやすく効率のよいC#コードを書けるようになります。