C#プログラミングにおいて、文字列の扱いは避けて通れない非常に重要な要素です。
日常的な開発の中で、ダブルクォーテーションやバックスラッシュ、あるいは改行といった「特殊な意味を持つ記号」を、プログラム上の命令としてではなく、純粋な「データ(文字)」として扱いたい場面は多々あります。
特に、JSON形式のテキストをコード内で定義したり、正規表現やファイルパスを記述したりする際、適切な記述方法を知らないとコンパイルエラーや意図しないバグを招くことになります。
本記事では、C#における文字リテラルと文字列リテラルの基礎から、従来の「エスケープシーケンス」、便利な「逐次リテラル」、そしてモダンなC#開発には欠かせない「生文字列リテラル(Raw String Literals)」まで、あらゆる手法を網羅的に解説します。
最新の仕様に基づき、どのようなシーンでどの記述法を選択するのがベストなのかを詳しく見ていきましょう。
C#における文字と文字列の基本概念
C#でテキストを扱う際、まず理解しておくべきは「文字リテラル(char)」と「文字列リテラル(string)」の違いです。
これらは内部的なデータ構造が異なり、記述方法も明確に区別されています。
文字リテラル (char) の扱い
文字リテラルは、単一の文字を表すために使用されます。
C#において文字リテラルは必ずシングルクォーテーション '' で囲む必要があります。
内部的にはUnicode文字(UTF-16エンコーディング)として保持されます。
// 文字リテラルの基本
char initial = 'A';
char digit = '1';
char symbol = '$';
Console.WriteLine(initial);
Console.WriteLine(digit);
Console.WriteLine(symbol);
文字列リテラル (string) の扱い
一方で、複数の文字の並び(テキスト)を扱うのが文字列リテラルです。
文字列はダブルクォーテーション "" で囲みます。
// 文字列リテラルの基本
string greeting = "Hello, C#!";
string empty = ""; // 空文字
Console.WriteLine(greeting);
このように、シングルクォーテーションかダブルクォーテーションかによって、型が char なのか string なのかが決まるという点がC#の基本ルールです。
エスケープシーケンスによる特殊記号の表現
プログラムコードの中で「改行」を表現したり、文字列を囲むための記号である「ダブルクォーテーション」そのものを文字列の中に含めたりする場合、そのまま記述するとコンパイラが混乱してしまいます。
これを解決するのがエスケープシーケンスです。
主要なエスケープシーケンス一覧
C#ではバックスラッシュ(日本語環境では円記号 \)を前置することで、続く文字に特別な意味を持たせます。
| シーケンス | 意味 |
|---|---|
' | シングルクォーテーション |
" | ダブルクォーテーション |
\ | バックスラッシュ |
\n | 改行(ラインフィード) |
\r | 行頭復帰(キャリッジリターン) |
\t | 水平タブ |
\uXXXX | Unicode形式(16進数4桁) |
具体的な使用例
以下のコードでは、エスケープシーケンスを使用して複雑な文字列を定義しています。
using System;
class Program
{
static void Main()
{
// ダブルクォーテーションを含める
string quote = "彼は \"C#は素晴らしい\" と言った。";
// ファイルパス(バックスラッシュを重ねる)
string path = "C:\\Users\\Desktop\\Project\\main.cs";
// 改行とタブの組み合わせ
string multiLine = "一行目\n\t二行目(インデント付き)";
Console.WriteLine(quote);
Console.WriteLine(path);
Console.WriteLine(multiLine);
}
}
彼は "C#は素晴らしい" と言った。
C:\Users\Desktop\Project\main.cs
一行目
二行目(インデント付き)
エスケープシーケンスは基本中の基本ですが、バックスラッシュが連続するファイルパスなどは可読性が低下するという欠点があります。
逐次リテラル(@マーク)の活用
エスケープシーケンスの煩雑さを解消するために用意されているのが、逐次文字列リテラル(Verbatim String Literals)です。
文字列の開始ダブルクォーテーションの前に @ 記号を付けることで、バックスラッシュをエスケープとして解釈せず、そのままの文字として扱うことができます。
逐次リテラルのメリット
最大のメリットは、Windowsのファイルパスや正規表現をそのまま記述できる点にあります。
// エスケープが必要な書き方
string normalPath = "C:\\Windows\\System32\\drivers";
// 逐次リテラル(直感的に書ける)
string verbatimPath = @"C:\Windows\System32\drivers";
また、逐次リテラル内では「ソースコード上の改行」がそのまま文字列としての改行として保持されます。
逐次リテラル内でのダブルクォーテーション
逐次リテラルを使用している際、ダブルクォーテーションそのものを表現したい場合は、"" のようにダブルクォーテーションを2回続けて記述します。
string message = @"彼は ""こんにちは"" と笑った。";
Console.WriteLine(message); // 出力: 彼は "こんにちは" と笑った。
文字列補完($マーク)との組み合わせ
C# 6.0から導入された文字列補完(String Interpolation)は、文字列の中に変数の値を直接埋め込むことができる強力な機能です。
基本的な書き方
文字列の前に $ を付け、変数名を {} で囲みます。
string name = "アリス";
int age = 25;
string info = $"名前: {name}, 年齢: {age}";
逐次リテラルとの併用($@ または @$)
$ と @ を同時に使用することも可能です(C# 8.0以降は順不同になりました)。
これにより、変数の埋め込みを行いつつ、エスケープなしでパスを記述したり、複数行のメッセージを作成したりできます。
string userName = "Taro";
string script = $@"C:\Users\{userName}\Documents\script.py";
Console.WriteLine(script);
最新機能:生文字列リテラル(Raw String Literals)
C# 11から導入された生文字列リテラル(Raw String Literals)は、文字列の扱いを劇的に進化させました。
これは、特にJSONやXML、SQLクエリなどをコード内に直接貼り付けたい場合に絶大な威力を発揮します。
生文字列リテラルの定義方法
生文字列リテラルは、最低3つ以上のダブルクォーテーション """ で囲みます。
string raw = """
これは「生文字列リテラル」です。
エスケープシーケンス(\nや\")は一切不要です。
"ダブルクォーテーション" もそのまま書けます。
""";
特徴1:エスケープからの完全な解放
生文字列リテラルの中では、バックスラッシュはただの文字として扱われ、ダブルクォーテーションもそのまま記述できます。
特徴2:インデントの自動調整
開始の """ の次の行から記述を始め、終了の """ の位置に合わせてインデントが自動的に除去されます。
これにより、コードのインデントを崩さずに可読性の高い複数行テキストを定義できます。
特徴3:クォーテーション数の柔軟性
もし、文字列の内容自体に """ が含まれる場合は、囲み記号の数を4つ("""")に増やすことで対応できます。
内容に含まれるクォーテーションの数よりも多い数で囲む、というルールです。
生文字列リテラルと文字列補完の高度な連携
生文字列リテラルでも $ を使った補完が可能です。
さらに、$$ のように $ を複数記述することで、{} そのものを文字列として扱いやすくなります。
例えば、JSONを記述する場合、JSON自体の波括弧と補完用の波括弧を区別するために、$$ を使用します。
この場合、変数の埋め込みには {{変数名}} と二重の波括弧が必要になります。
string title = "C#入門";
string json = $$"""
{
"title": "{{title}}",
"description": "最新のC#機能を解説します。"
}
""";
実践的な活用シーン別ガイド
ここからは、実際の開発現場で遭遇する具体的なケースにおいて、どの手法を選択すべきかを解説します。
ケース1:Windowsのファイルパスを定義する
Windows環境のパスはバックスラッシュを含みます。
- 推奨:逐次リテラル(@””)
逐次リテラルが最も簡潔です。
動的にパスを生成する場合は補完も組み合わせましょう。
string folder = "AppLogs";
string fullPath = @$"C:\ProgramData\{folder}\log.txt";
ケース2:JSONなどの構造化テキストをハードコードする
設定値のデフォルトなどをJSONで持ちたい場合です。
- 推奨:生文字列リテラル(”””…”””)
エスケープまみれのJSONはメンテナンス性が最悪ですが、生文字列リテラルならIDEからそのままコピー&ペーストできます。
string configJson = """
{
"ConnectionStrings": {
"DefaultConnection": "Server=myServerAddress;Database=myDataBase;"
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
""";
ケース3:正規表現(Regex)パターンを作成する
正規表現には多くのバックスラッシュや記号が登場します。
- 推奨:逐次リテラル(@””)
正規表現内でのエスケープとC#言語としてのエスケープが混ざると非常に混乱するため、逐次リテラルで「そのまま」記述するのが鉄則です。
using System.Text.RegularExpressions;
// 数字3桁-4桁-4桁の電話番号にマッチさせる例
string pattern = @"^\d{3}-\d{4}-\d{4}$";
bool isValid = Regex.IsMatch("090-1234-5678", pattern);
Unicodeと特殊な文字操作
記号や文字を扱う際、キーボードから直接入力できない文字(絵文字や数学記号、非公開領域の文字など)を扱う必要が出てくることもあります。
Unicodeエスケープの利用
\u に続けて4桁の16進数、または \U に続けて8桁の16進数を指定することで、任意のUnicode文字を表現できます。
string copyright = "\u00A9 2026 TechCorp"; // ©記号
string emoji = "\U0001F600"; // 笑顔の絵文字 😀
UTF-8 文字列リテラル (C# 11以降)
パフォーマンスを重視するWebアプリケーションやネットワーク通信では、文字列をUTF-16(C#の標準)ではなくUTF-8として扱いたい場合があります。
C# 11からは、文字列の末尾に u8 サフィックスを付けることで、ReadOnlySpan<byte> 型のUTF-8データを直接生成できるようになりました。
// UTF-8バイト配列として直接定義
var utf8Buffer = "Hello UTF-8"u8;
// 通常のstringではなく、ReadOnlySpan<byte>になる
Console.WriteLine(utf8Buffer.Length);
これにより、実行時のエンコーディング変換コストを削減できるため、高頻度で呼ばれる処理において非常に有効です。
記号の扱いに関する注意点とベストプラクティス
最後に、C#で文字や記号を扱う上での重要な注意点をまとめます。
1. 読みやすさ(可読性)を最優先する
エスケープシーケンス " が1つか2つ程度なら通常の文字列リテラルで問題ありませんが、3つ以上出てくる場合や改行を含む場合は、迷わず生文字列リテラルか逐次リテラルに切り替えるべきです。
2. 環境依存の改行コードに注意
逐次リテラルや生文字列リテラルで複数行を記述した場合、そのソースファイル自体の改行コード(CRLFかLFか)がそのまま文字列の改行コードとして反映されます。
異なるOS間で開発を行う場合、Gitの設定(core.autocrlf など)によって文字列の内容が変わってしまう可能性があるため、厳密な改行コードの指定が必要な場合は \n や Environment.NewLine を明示的に使用するのが安全です。
3. 文字列の比較
記号を含む文字列を比較する際は、全角・半角の違いや、Unicodeの正規化(結合文字などの扱い)に注意が必要です。
必要に応じて StringComparison.OrdinalIgnore記号 などのオプションを活用しましょう。
まとめ
C#で記号やダブルクォーテーションを文字として扱う方法は、言語の進化とともに洗練されてきました。
- 基本的な記号の表現にはエスケープシーケンス(\)。
- パスや正規表現には逐次リテラル(@)。
- JSONや複数行の複雑なテキストには最新の生文字列リテラル(”””)。
- 動的な値の埋め込みには文字列補完($)。
これらの機能を適切に組み合わせることで、エラーを防ぐだけでなく、誰が見ても理解しやすいクリーンなコードを書くことができます。
特に、C# 11以降で導入された生文字列リテラルは、現代のデータ駆動なプログラミングにおいて必須のスキルと言えるでしょう。
この記事を参考に、用途に応じた最適な文字列の記述法を選択し、より効率的なC#開発を実践してください。






