C#の開発において、文字列の中にダブルクォーテーションやバックスラッシュが頻出する場合、エスケープシーケンスの記述に苦労した経験はないでしょうか。
特にJSONやXML、SQLクエリなどをソースコード内に直接記述する際、従来の手法では可読性が著しく低下するという課題がありました。
C# 11で導入された生文字列リテラル(Raw String Literals)は、こうしたストレスを劇的に解消する画期的な機能です。
本記事では、複数行の記述やJSONとの相性、そして補完機能との組み合わせについて、具体的なサンプルコードを交えながら詳しく解説します。

生文字列リテラルの基本構造
生文字列リテラルの最大の特徴は、「記述した内容がそのまま文字列として扱われる」点にあります。
これまでのC#では、ダブルクォーテーションを表示するためには"のようにバックスラッシュを置く必要がありましたが、生文字列リテラルではその必要がありません。
3つ以上のダブルクォーテーションで囲む
生文字列リテラルを定義するには、最低3つのダブルクォーテーション(“””)で文字列を囲みます。
これにより、内部に含まれる単一または二重のダブルクォーテーションをエスケープなしでそのまま記述できるようになります。
using System;
class Program
{
static void Main()
{
// 従来の書き方(エスケープが必要)
string oldPath = "C:\\Windows\\System32";
string oldQuote = "He said, \"Hello!\"";
// 生文字列リテラル(見たまま記述可能)
string newPath = """C:\Windows\System32""";
string newQuote = """He said, "Hello!" """;
Console.WriteLine(newPath);
Console.WriteLine(newQuote);
}
}
C:\Windows\System32
He said, "Hello!"
もし、コンテンツの中に3つのダブルクォーテーションが含まれる場合は、開始と終了の識別子を4つ以上のダブルクォーテーションに増やすことで対応可能です。
つまり、「コンテンツに含まれる連続したダブルクォーテーションの数よりも多い数」で囲めば、どのような文字列も安全に表現できます。
複数行文字列の記述とインデントの制御
複数行にわたる文章やコードを記述する場合、生文字列リテラルは非常に強力な威力を発揮します。
従来の逐語的文字列@""では、ソースコードのインデントを下げると、その空白まで文字列に含まれてしまうという問題がありました。

終端識別子の位置が基準になる
複数行の生文字列リテラルでは、開始の「”””」の直後で改行し、終了の「”””」を単独の行に配置するのが基本ルールです。
このとき、終了の「”””」が配置されている列の位置が「基準の左端」として扱われます。
以下のコードを見てみましょう。
ソースコード上ではインデントされていますが、出力される文字列からは不要な空白が自動的に取り除かれます。
using System;
class Program
{
static void Main()
{
// 終了の「"""」の位置に合わせて左側の空白がカットされる
string message = """
これは複数行の
生文字列リテラルです。
インデントが維持されます。
""";
Console.WriteLine("---開始---");
Console.WriteLine(message);
Console.WriteLine("---終了---");
}
}
---開始---
これは複数行の
生文字列リテラルです。
インデントが維持されます。
---終了---
この機能のおかげで、プログラムの構造(ネスト)を崩さずに、読みやすい形で定数やテンプレートを定義できるようになります。
もし、意図的に先頭に空白を入れたい場合は、終了の「”””」をさらに左側にずらすだけで調整が可能です。
JSONを美しく記述する方法
近年のアプリケーション開発において、JSON形式のデータを取り扱う機会は非常に多いです。
しかし、JSONはキーや値にダブルクォーテーションを多用するため、C#の文字列として記述するのは非常に手間がかかる作業でした。
文字列補完($)との組み合わせ
C# 11の生文字列リテラルは、文字列補完($記号)と組み合わせることができます。
さらに強力なのが、$記号を複数並べる機能です。
JSONでは中括弧{}が構文として使われます。
通常の文字列補完$""では、中括弧を表示するために{{のように二重にする必要がありました。
しかし、生文字列リテラルでは$$"""のように$を2つ繋げることで、「中括弧2つ{{ }}が揃ったときだけ変数展開する」というルールに変更できます。

using System;
class Program
{
static void Main()
{
var userName = "田中 太郎";
var userAge = 30;
// $$を使うことで、単一の { } はJSONの構造としてそのまま扱える
// 変数展開したい場所だけ {{ }} で囲む
string json = $$"""
{
"user": {
"name": "{{userName}}",
"age": {{userAge}},
"status": "active"
}
}
""";
Console.WriteLine(json);
}
}
{
"user": {
"name": "田中 太郎",
"age": 30,
"status": "active"
}
}
この記法を使えば、JSONのフォーマットを崩さず、コピー&ペーストした内容にそのまま変数だけを埋め込むといった作業が極めて容易になります。
従来手法との比較まとめ
C#にはこれまでも複数の文字列記述法がありました。
それぞれの特徴を整理してみましょう。
| 機能 | 通常の文字列 (“”) | 逐語的文字列 (@””) | 生文字列リテラル (“””) |
|---|---|---|---|
| 改行の扱い | エスケープ (\n) が必要 | そのまま改行可能 | そのまま改行可能 |
| 引用符 (“) | エスケープ (“) が必要 | 二重 (“”) にする必要あり | エスケープ不要 |
| インデント調整 | 不可 | ソースの空白が混入する | 自動で削除される |
| 文字列補完 | 可能 | 可能 | 複数$による制御が可能 |
従来の@""(逐語的文字列)も便利でしたが、ダブルクォーテーションを""と書かなければならない点が、JSONやHTMLを扱う際のネックとなっていました。
生文字列リテラルは、それらの弱点をすべて克服した、まさに完全版と言える機能です。
実践的な活用シーン
生文字列リテラルは、単なる可読性の向上だけでなく、保守性の向上にも寄与します。
SQLクエリの埋め込み
複雑なSQLをソースコードに記述する場合、生文字列リテラルを使えばデータベース管理ツールで作成したクエリをそのまま貼り付けられます。
string sql = """
SELECT id, name, email
FROM users
WHERE created_at >= '2024-01-01'
AND status = 'active'
ORDER BY id DESC;
""";
XMLやHTMLのテンプレート
タグ構造を持つドキュメントも、インデントを維持したまま直感的に記述できます。
string html = $$"""
<div class="user-card">
<h1>{{userName}}</h1>
<p>Welcome to our service.</p>
</div>
""";
ユニットテストの期待値
テストコードにおいて、出力結果の検証を行う際、期待される複数行の文字列を定義するのに最適です。
期待値を外部ファイルに持たせる手間が省け、テストコードの見通しが良くなります。
注意点と制約
非常に便利な生文字列リテラルですが、いくつか覚えておくべきルールがあります。
- 開始の「”””」の行には、その後に改行以外の文字を置いてはいけません。
- 終了の「”””」の行にも、その前に改行以外の文字を置いてはいけません。
- インデントの基準となるのは終了識別子の位置であるため、文字列の本文が終了識別子よりも左側から始まっているとコンパイルエラーになります。
これらのルールは一見厳しく感じられますが、「見た目と中身の一致」を保証するための重要な仕組みです。
まとめ
C# 11で導入された生文字列リテラルは、モダンな開発における文字列操作のスタンダードとなる機能です。
エスケープシーケンスによる視覚的なノイズを排除し、JSONやSQLといった外部形式のデータを美しく、かつ安全にソースコードへ組み込むことが可能になりました。
特に$$"""による柔軟な補完制御と、終了識別子に基づいたインデントの自動調整機能は、一度使うと手放せないほど強力です。
今後、データのテンプレート作成やテストコードの記述において、積極的にこの機能を活用していくことをお勧めします。
これにより、あなたのコードはより「読みやすく、壊れにくい」ものへと進化するでしょう。
