C# stringの使い方完全ガイド|文字列操作・比較・変換・null判定を初心者向けに解説

はじめに

C#でアプリケーションを作るうえで、stringは必ずと言ってよいほど使う基本的な型です。画面に表示するメッセージ、ユーザーが入力した名前、ファイルパス、メールアドレス、ログ、JSON、CSVなど、文字列を扱う場面は非常に多くあります。

一方で、C#のstringには「参照型だが値のように比較できる」「一度作ると変更できない」「nullと空文字は違う」「比較方法によって結果が変わる」といった、初心者がつまずきやすいポイントもあります。

この記事では、C# stringの基本から、文字列操作、比較、変換、null判定、フォーマット、パフォーマンス、よくあるエラーまでを初心者向けにわかりやすく解説します。

1. C#のstringとは?まず押さえる文字列の基本

1-1. stringは文字列を扱うための型

C#のstringは、文字列を扱うための型です。

C#
string message = "Hello, C#";
Console.WriteLine(message);

"Hello, C#"のようにダブルクォーテーションで囲んだ値を文字列リテラルと呼びます。ユーザー名、住所、エラーメッセージ、検索キーワードなど、文字の並びを扱いたいときにstringを使います。

C#
string name = "田中";
string email = "sample@example.com";
string keyword = "csharp string";

C#では文字列を扱う機会が非常に多いため、stringの使い方を理解しておくことはとても重要です。

1-2. stringとSystem.Stringの違い

C#のstringは、.NETのSystem.Stringの別名です。

C#
string text1 = "abc";
System.String text2 = "abc";

この2つは基本的に同じ意味です。

一般的なC#のコードでは、型名としてはstringを使うことが多いです。一方、静的メソッドを呼び出すときにはstring.IsNullOrEmptyのように書くのが一般的です。

C#
string text = "hello";

bool result = string.IsNullOrEmpty(text);

Stringと大文字で書く場合もありますが、C#ではキーワードであるstringを使うと読みやすく、他の基本型であるintboolとも書き方をそろえやすくなります。

1-3. stringは参照型だが値のように扱える

C#のstringは参照型です。参照型とは、値そのものではなくオブジェクトへの参照を変数が持つ型のことです。

ただし、stringは特別に、値型のような感覚で扱えるようになっています。たとえば、==演算子で文字列の内容を比較できます。

C#
string a = "hello";
string b = "hello";

Console.WriteLine(a == b); // True

通常の参照型では、==が参照先の同一性を比較する場合があります。しかしstringでは、基本的に文字列の内容が同じかどうかを比較できます。

そのため、初心者にとってはintboolのような基本型に近い感覚で使えます。

1-4. stringは変更できない「イミュータブル」な型

C#のstringはイミュータブルな型です。イミュータブルとは、一度作成された値を変更できないという意味です。

たとえば、次のコードを見てみます。

C#
string text = "abc";
text = text + "def";

Console.WriteLine(text); // abcdef

一見すると、textの中身が変更されたように見えます。しかし実際には、元の"abc"が変更されたのではなく、"abcdef"という新しい文字列が作られ、textがそれを参照するようになっています。

この性質は安全性の面では便利ですが、大量の文字列連結を行うとパフォーマンスに影響することがあります。

1-5. charとの違いと文字列の内部構造

charは1つの文字を表す型です。一方、stringは複数のcharが並んだ文字列です。

C#
char c = 'A';
string text = "ABC";

charはシングルクォーテーション、stringはダブルクォーテーションで囲みます。

C#
char letter = 'A';
string word = "Apple";

文字列の各文字には、インデックスを使ってアクセスできます。インデックスは0から始まります。

C#
string text = "ABC";

Console.WriteLine(text[0]); // A
Console.WriteLine(text[1]); // B
Console.WriteLine(text[2]); // C

ただし、日本語や絵文字などを扱う場合、見た目の1文字とcharの1要素が必ず一致するとは限りません。基本的な文字列操作では問題にならないことも多いですが、厳密な文字数カウントが必要な場合は注意が必要です。

2. C#でstringを宣言・初期化する方法

2-1. 文字列リテラルで代入する基本形

C#でstringを宣言する基本形は次のとおりです。

C#
string name = "佐藤";
string message = "こんにちは";

左側のstringが型、namemessageが変数名、右側の"佐藤""こんにちは"が文字列です。

宣言だけして、あとから値を代入することもできます。

C#
string text;
text = "C#の文字列";

ただし、値を代入する前に使おうとするとエラーになるため、基本的には宣言と同時に初期化する書き方がわかりやすいです。

2-2. 空文字を代入する方法

空文字とは、文字数が0の文字列です。

C#
string text = "";

空文字はnullとは異なります。空文字は「文字列オブジェクトは存在するが、中身が空」という状態です。

C#
string text = "";

Console.WriteLine(text.Length); // 0

Lengthを呼び出してもエラーにはなりません。

2-3. nullを代入する場合の注意点

nullは、変数がどの文字列オブジェクトも参照していない状態です。

C#
string text = null;

この状態でLengthなどのメンバーにアクセスすると、NullReferenceExceptionが発生します。

C#
string text = null;

// Console.WriteLine(text.Length); // NullReferenceException

そのため、nullの可能性がある文字列を扱うときは、先にnull判定を行う必要があります。

C#
if (text != null)
{
Console.WriteLine(text.Length);
}

2-4. varでstringを宣言する方法

C#ではvarを使って、型をコンパイラに推論させることもできます。

C#
var text = "Hello";

この場合、右側が文字列リテラルなので、textの型はstringになります。

ただし、varは型がなくなるわけではありません。あくまでコンパイラが型を判断しているだけです。

C#
var name = "田中"; // string
var age = 20; // int

初心者のうちは、型を明確に理解するためにstringと書くのもおすすめです。慣れてきたら、コードの読みやすさに応じてvarを使うとよいでしょう。

2-5. string.Emptyと""の違い

空文字を表す方法には、""string.Emptyがあります。

C#
string text1 = "";
string text2 = string.Empty;

どちらも空文字を表します。実用上の違いはほとんどありません。

""は短く直感的です。string.Emptyは「空の文字列である」ことが明確に伝わります。

C#
string result = string.Empty;

チームやプロジェクトのコーディング規約に合わせて使い分ければ問題ありません。最近のC#コードでは、シンプルに""を使うケースも多くあります。

3. C#の文字列リテラルの種類と使い分け

3-1. 通常の文字列リテラル

通常の文字列リテラルは、ダブルクォーテーションで囲んで書きます。

C#
string text = "Hello";
string message = "こんにちは";

短いメッセージや単純な文字列を書くときに使います。

C#
Console.WriteLine("C# stringの基本");

文字列内に改行やダブルクォーテーションを含めたい場合は、エスケープシーケンスを使います。

3-2. エスケープシーケンスの使い方

エスケープシーケンスは、バックスラッシュを使って特殊な文字を表す方法です。

C#
string text = "1行目\n2行目";
Console.WriteLine(text);

よく使うエスケープシーケンスには次のようなものがあります。

C#
string newLine = "こんにちは\nこんばんは";
string tab = "名前\t年齢";
string quote = "彼は\"Hello\"と言いました";
string backslash = "C:\\Users\\Sample";

\nは改行、\tはタブ、\"はダブルクォーテーション、\\はバックスラッシュを表します。

ファイルパスのようにバックスラッシュが多い文字列では、通常の文字列リテラルだと読みづらくなることがあります。

3-3. 逐語的文字列リテラル(@)の使い方

逐語的文字列リテラルは、先頭に@を付けて書きます。

C#
string path = @"C:\Users\Sample\Documents";

@を付けると、バックスラッシュをエスケープせずにそのまま書けます。そのため、Windowsのファイルパスを書くときに便利です。

複数行の文字列もそのまま書けます。

C#
string text = @"1行目
2行目
3行目";

ただし、文字列内にダブルクォーテーションを含めたい場合は、""のように2つ続けて書きます。

C#
string message = @"彼は""Hello""と言いました";

3-4. 文字列補間($)の使い方

文字列補間は、文字列の中に変数や式を埋め込む書き方です。先頭に$を付けます。

C#
string name = "田中";
int age = 25;

string message = $"名前は{name}、年齢は{age}歳です。";
Console.WriteLine(message);

+演算子で連結するよりも読みやすく、ミスも減らせます。

C#
string message1 = "名前は" + name + "、年齢は" + age + "歳です。";
string message2 = $"名前は{name}、年齢は{age}歳です。";

実務では、表示メッセージやログ出力などでよく使います。

3-5. 生文字列リテラルの使い方

C# 11以降では、生文字列リテラルを使えます。生文字列リテラルは、3つ以上のダブルクォーテーションで囲みます。

C#
string json = """
{
"name": "Taro",
"age": 30
}
""";

JSON、SQL、HTMLなど、ダブルクォーテーションや改行を多く含む文字列を書くときに便利です。

文字列補間と組み合わせることもできます。

C#
string name = "Taro";

string json = $$"""
{
"name": "{{name}}"
}
""";

生文字列リテラルを使うと、エスケープが少なくなり、長い文字列を読みやすく書けます。

3-6. パス・改行・JSON文字列を書くときの使い分け

文字列リテラルは、用途に応じて使い分けると読みやすくなります。

ファイルパスを書くなら、逐語的文字列リテラルが便利です。

C#
string path = @"C:\work\sample.txt";

短いメッセージなら、通常の文字列リテラルで十分です。

C#
string message = "処理が完了しました";

変数を埋め込みたいなら、文字列補間を使います。

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

JSONや複数行テキストを書くなら、生文字列リテラルが読みやすいです。

C#
string json = """
{
"status": "ok",
"message": "success"
}
""";

4. C# stringの基本操作

4-1. 文字列を連結する

文字列を連結するには、+演算子を使えます。

C#
string firstName = "太郎";
string lastName = "山田";

string fullName = lastName + firstName;
Console.WriteLine(fullName); // 山田太郎

区切り文字を入れることもできます。

C#
string fullName = lastName + " " + firstName;

変数を含む文章を作る場合は、文字列補間のほうが読みやすいです。

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

複数の要素を区切って結合する場合は、string.Joinも便利です。

C#
string[] names = { "佐藤", "鈴木", "高橋" };
string result = string.Join(", ", names);

Console.WriteLine(result); // 佐藤, 鈴木, 高橋

4-2. 文字列の長さを取得する

文字列の長さはLengthプロパティで取得します。

C#
string text = "Hello";
Console.WriteLine(text.Length); // 5

空文字の場合は0になります。

C#
string empty = "";
Console.WriteLine(empty.Length); // 0

ただし、nullの文字列に対してLengthを呼び出すとエラーになります。

C#
string text = null;

// Console.WriteLine(text.Length); // エラー

nullの可能性がある場合は、先にチェックしましょう。

4-3. 指定位置の文字を取得する

文字列の指定位置の文字を取得するには、インデックスを使います。

C#
string text = "CSharp";

char first = text[0];
char second = text[1];

Console.WriteLine(first); // C
Console.WriteLine(second); // S

インデックスは0から始まります。最後の文字を取得するには、Length - 1を使います。

C#
char last = text[text.Length - 1];
Console.WriteLine(last); // p

範囲外のインデックスを指定すると例外が発生するため注意が必要です。

C#
// Console.WriteLine(text[100]); // IndexOutOfRangeException

4-4. 部分文字列を取り出す

文字列の一部を取り出すには、Substringを使います。

C#
string text = "Hello World";

string part = text.Substring(0, 5);
Console.WriteLine(part); // Hello

第1引数は開始位置、第2引数は取り出す文字数です。

C#
string text = "CSharp";

Console.WriteLine(text.Substring(1, 3)); // Sha

開始位置だけを指定すると、その位置から最後まで取り出します。

C#
string result = text.Substring(1);
Console.WriteLine(result); // Sharp

指定範囲が文字列の長さを超えると例外が発生するため、長さを確認してから使うと安全です。

4-5. 文字列を検索する

文字列の中から特定の文字列を探すには、IndexOfを使います。

C#
string text = "Hello World";

int index = text.IndexOf("World");
Console.WriteLine(index); // 6

見つからなかった場合は-1が返ります。

C#
int index = text.IndexOf("C#");
Console.WriteLine(index); // -1

検索結果を使って処理を分ける場合は、次のように書けます。

C#
if (text.IndexOf("World") >= 0)
{
Console.WriteLine("見つかりました");
}

ただし、含まれるかどうかだけを知りたい場合は、Containsのほうが読みやすいです。

4-6. 文字列に含まれるか判定する

文字列に特定の文字列が含まれているかを判定するには、Containsを使います。

C#
string text = "C# string guide";

bool result = text.Contains("string");

Console.WriteLine(result); // True

Containsは、検索キーワードの存在確認に便利です。

C#
string keyword = "C#";

if (text.Contains(keyword))
{
Console.WriteLine("キーワードが含まれています");
}

大文字小文字を区別したくない場合は、StringComparisonを指定します。

C#
bool result = text.Contains("STRING", StringComparison.OrdinalIgnoreCase);

4-7. 先頭・末尾の文字列を判定する

文字列が特定の文字列で始まるかどうかは、StartsWithで判定します。

C#
string text = "sample.txt";

Console.WriteLine(text.StartsWith("sample")); // True

特定の文字列で終わるかどうかは、EndsWithで判定します。

C#
Console.WriteLine(text.EndsWith(".txt")); // True

ファイル拡張子のチェックやURLの判定などでよく使います。

C#
if (text.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("テキストファイルです");
}

比較条件を明確にするため、実務ではStringComparisonを指定するのがおすすめです。

5. C# stringでよく使う文字列操作メソッド

5-1. Replaceで文字列を置換する

Replaceは、文字列の一部を別の文字列に置き換えるメソッドです。

C#
string text = "Hello World";
string result = text.Replace("World", "C#");

Console.WriteLine(result); // Hello C#

元の文字列は変更されず、新しい文字列が返されます。

C#
string original = "abc";
string replaced = original.Replace("a", "A");

Console.WriteLine(original); // abc
Console.WriteLine(replaced); // Abc

これはstringがイミュータブルであるためです。Replaceを呼び出しただけでは元の変数の内容は変わらない点に注意しましょう。

C#
text.Replace("Hello", "Hi"); // 結果を受け取らないと意味がない
text = text.Replace("Hello", "Hi");

5-2. Trimで前後の空白を削除する

Trimは、文字列の前後にある空白を削除します。

C#
string text = "  hello  ";
string result = text.Trim();

Console.WriteLine(result); // hello

ユーザー入力の前後に余分な空白が入ることはよくあるため、入力チェック前にTrimを使うことがあります。

C#
string input = "  test@example.com  ";
string email = input.Trim();

先頭だけ削除したい場合はTrimStart、末尾だけ削除したい場合はTrimEndを使います。

C#
string result1 = text.TrimStart();
string result2 = text.TrimEnd();

5-3. ToUpper・ToLowerで大文字小文字を変換する

ToUpperは大文字に、ToLowerは小文字に変換します。

C#
string text = "Hello";

Console.WriteLine(text.ToUpper()); // HELLO
Console.WriteLine(text.ToLower()); // hello

検索や比較の前処理で使うことがあります。

C#
string input = "ADMIN";

if (input.ToLower() == "admin")
{
Console.WriteLine("管理者です");
}

ただし、比較目的で大文字小文字を無視したい場合は、ToLowerで変換するよりもStringComparison.OrdinalIgnoreCaseを使うほうが安全で明確です。

C#
if (string.Equals(input, "admin", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("管理者です");
}

5-4. Splitで文字列を分割する

Splitは、区切り文字で文字列を分割して配列にします。

C#
string csv = "apple,banana,orange";

string[] fruits = csv.Split(',');

foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}

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

C#
apple
banana
orange

空白を含む場合は、Trimと組み合わせると扱いやすくなります。

C#
string csv = "apple, banana, orange";

string[] items = csv.Split(',');

foreach (string item in items)
{
Console.WriteLine(item.Trim());
}

5-5. Joinで配列を文字列に結合する

Joinは、配列やリストの要素を指定した区切り文字で結合します。

C#
string[] names = { "佐藤", "鈴木", "高橋" };

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

Console.WriteLine(result); // 佐藤, 鈴木, 高橋

CSV風の文字列を作りたいときや、ログ出力で複数の値をまとめたいときに便利です。

C#
int[] numbers = { 1, 2, 3 };

string text = string.Join("-", numbers);
Console.WriteLine(text); // 1-2-3

5-6. PadLeft・PadRightで桁埋めする

PadLeftは左側を指定文字で埋めます。

C#
string number = "42";

string result = number.PadLeft(5, '0');

Console.WriteLine(result); // 00042

PadRightは右側を埋めます。

C#
string text = "abc";

string result = text.PadRight(6, '-');

Console.WriteLine(result); // abc---

番号のゼロ埋めや、固定幅の表示を作るときに使えます。

5-7. Remove・Insertで文字列を編集する

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

C#
string text = "Hello World";

string result = text.Remove(5);

Console.WriteLine(result); // Hello

削除する文字数を指定することもできます。

C#
string result = text.Remove(5, 1);
Console.WriteLine(result); // HelloWorld

Insertは、指定した位置に文字列を挿入します。

C#
string text = "HelloWorld";

string result = text.Insert(5, " ");

Console.WriteLine(result); // Hello World

RemoveInsertも元の文字列を変更するのではなく、新しい文字列を返します。

6. C# stringの比較方法

6-1. ==演算子で比較する

C#のstringは、==演算子で文字列の内容を比較できます。

C#
string a = "hello";
string b = "hello";

Console.WriteLine(a == b); // True

内容が異なればfalseになります。

C#
string a = "hello";
string b = "Hello";

Console.WriteLine(a == b); // False

==は簡単で読みやすいため、単純な比較ではよく使われます。

ただし、大文字小文字を無視したい場合や、文化依存の比較を避けたい場合は、StringComparisonを指定できるメソッドを使うほうが安全です。

6-2. Equalsで比較する

Equalsでも文字列を比較できます。

C#
string a = "hello";
string b = "hello";

Console.WriteLine(a.Equals(b)); // True

ただし、変数がnullの場合は注意が必要です。

C#
string a = null;
string b = "hello";

// Console.WriteLine(a.Equals(b)); // NullReferenceException

anullだと、a.Equals(b)は呼び出せません。nullの可能性がある場合は、次に紹介するstring.Equalsを使うと安全です。

6-3. string.Equalsでnull安全に比較する

string.Equalsは、null安全に文字列を比較できます。

C#
string a = null;
string b = "hello";

bool result = string.Equals(a, b);

Console.WriteLine(result); // False

大文字小文字を無視した比較もできます。

C#
string a = "HELLO";
string b = "hello";

bool result = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

Console.WriteLine(result); // True

実務では、文字列比較の意図を明確にするために、StringComparisonを指定したstring.Equalsを使うことが多いです。

6-4. Compare・CompareToで大小比較する

文字列の大小比較には、CompareCompareToを使います。

C#
string a = "apple";
string b = "banana";

int result = string.Compare(a, b);

Console.WriteLine(result); // 0未満

戻り値の意味は次のとおりです。

C#
// 0未満: aはbより前
// 0: aとbは同じ
// 0より大きい: aはbより後

CompareToも似ています。

C#
int result = a.CompareTo(b);

並び替えやソート条件を自分で制御したい場合に使います。

6-5. 大文字小文字を区別しない比較

大文字小文字を区別しない比較には、StringComparison.OrdinalIgnoreCaseを使うのがおすすめです。

C#
string input = "ADMIN";

if (string.Equals(input, "admin", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("一致しました");
}

ToLowerToUpperで変換してから比較する方法もありますが、余計な文字列が作られたり、文化依存の問題が起きたりする可能性があります。

C#
// あまりおすすめしない
if (input.ToLower() == "admin")
{
Console.WriteLine("一致しました");
}

比較の意図を明確にするためにも、StringComparisonを指定しましょう。

6-6. StringComparisonを指定すべき理由

StringComparisonを指定すると、どのルールで文字列を比較するかを明確にできます。

よく使う指定は次の2つです。

C#
StringComparison.Ordinal
StringComparison.OrdinalIgnoreCase

Ordinalは、文字のコード値に基づく比較です。ID、キー、ファイル拡張子、プログラム内部の値など、文化に依存しない比較に向いています。

C#
bool result = string.Equals(a, b, StringComparison.Ordinal);

大文字小文字を無視したい場合は、OrdinalIgnoreCaseを使います。

C#
bool result = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

表示用の自然な並び替えなどでは文化依存の比較を使うこともありますが、初心者のうちは、まずOrdinal系を基本として覚えるとよいでしょう。

6-7. 文字列比較で初心者が間違えやすいポイント

初心者がよく間違えるのは、比較の前に余分な空白や改行を取り除いていないケースです。

C#
string input = "admin ";
Console.WriteLine(input == "admin"); // False

見た目では同じように見えても、末尾に空白があるため一致しません。

C#
string input = "admin ";
Console.WriteLine(input.Trim() == "admin"); // True

また、大文字小文字の違いにも注意が必要です。

C#
string input = "Admin";
Console.WriteLine(input == "admin"); // False

大文字小文字を無視するなら、次のように書きます。

C#
bool result = string.Equals(input, "admin", StringComparison.OrdinalIgnoreCase);

文字列比較では、空白、大文字小文字、null、文化依存の4点を意識することが大切です。

7. C# stringの変換方法

7-1. 数値をstringに変換する

数値を文字列に変換するには、ToStringを使います。

C#
int number = 123;

string text = number.ToString();

Console.WriteLine(text); // 123

文字列補間を使って変換することもできます。

C#
int age = 20;

string message = $"年齢は{age}歳です";

この場合、ageは自動的に文字列として扱われます。

C#
double price = 123.45;
string text = price.ToString();

表示形式を指定したい場合は、書式指定を使います。

7-2. stringをintやdoubleに変換する

文字列を数値に変換するには、int.Parsedouble.Parseを使います。

C#
string text = "123";

int number = int.Parse(text);

Console.WriteLine(number); // 123

小数に変換する場合は、double.Parseを使います。

C#
string text = "123.45";

double value = double.Parse(text);

Console.WriteLine(value); // 123.45

ただし、変換できない文字列を渡すとFormatExceptionが発生します。

C#
string text = "abc";

// int number = int.Parse(text); // FormatException

ユーザー入力など、値が正しいとは限らない場合はTryParseを使いましょう。

7-3. ParseとTryParseの違い

Parseは、変換できない場合に例外を発生させます。

C#
int number = int.Parse("123");

一方、TryParseは変換に成功したかどうかをboolで返します。

C#
string text = "123";

if (int.TryParse(text, out int number))
{
Console.WriteLine($"変換成功: {number}");
}
else
{
Console.WriteLine("変換できません");
}

ユーザー入力、CSV、外部ファイル、Web APIの値など、信頼できない文字列を変換する場合は、TryParseを使うのが安全です。

C#
string input = "abc";

if (!int.TryParse(input, out int value))
{
Console.WriteLine("数値を入力してください");
}

7-4. DateTimeとstringを相互変換する

日付を文字列に変換するには、ToStringを使います。

C#
DateTime now = DateTime.Now;

string text = now.ToString("yyyy/MM/dd");

Console.WriteLine(text);

文字列を日付に変換するには、DateTime.ParseまたはDateTime.TryParseを使います。

C#
string text = "2026/06/14";

DateTime date = DateTime.Parse(text);

Console.WriteLine(date);

安全に変換したい場合は、TryParseを使います。

C#
if (DateTime.TryParse(text, out DateTime date))
{
Console.WriteLine(date);
}
else
{
Console.WriteLine("日付に変換できません");
}

決まった形式の日付だけを受け付けたい場合は、DateTime.TryParseExactも使えます。

7-5. ToStringで書式を指定する

ToStringでは、数値や日付の表示形式を指定できます。

C#
int price = 1200000;

string text = price.ToString("N0");

Console.WriteLine(text); // 1,200,000

小数点以下の桁数も指定できます。

C#
double rate = 0.1234;

Console.WriteLine(rate.ToString("P2")); // 12.34%

日付の書式指定もよく使います。

C#
DateTime date = new DateTime(2026, 6, 14);

Console.WriteLine(date.ToString("yyyy年MM月dd日")); // 2026年06月14日

表示用の文字列を作るときに便利です。

7-6. 変換エラーを防ぐ安全な書き方

変換エラーを防ぐには、TryParseを使うのが基本です。

C#
string input = "100";

if (int.TryParse(input, out int number))
{
Console.WriteLine(number * 2);
}
else
{
Console.WriteLine("数値ではありません");
}

さらに、入力値の前後に空白が入る可能性がある場合は、Trimを使います。

C#
string input = " 100 ";
input = input.Trim();

if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}

nullや空文字の可能性がある場合は、先にチェックします。

C#
if (!string.IsNullOrWhiteSpace(input) &&
int.TryParse(input, out int number))
{
Console.WriteLine(number);
}

このように、null判定、空白除去、TryParseを組み合わせると安全な変換処理になります。

8. C# stringのnull判定・空文字判定

8-1. nullとは何か

nullとは、変数が何も参照していない状態です。

C#
string text = null;

textという変数は存在していますが、文字列オブジェクトを指していません。

この状態でメソッドやプロパティを呼び出すと、NullReferenceExceptionが発生します。

C#
string text = null;

// Console.WriteLine(text.Length); // NullReferenceException

nullの可能性がある文字列を扱う場合は、必ずチェックが必要です。

8-2. 空文字とは何か

空文字は、文字数が0の文字列です。

C#
string text = "";

空文字は文字列オブジェクトとして存在しています。そのため、Lengthを呼び出せます。

C#
string text = "";

Console.WriteLine(text.Length); // 0

空文字は「値はあるが中身が空」という状態です。

8-3. nullと空文字の違い

nullと空文字は同じではありません。

C#
string a = null;
string b = "";

Console.WriteLine(a == b); // False

nullは文字列が存在しない状態、空文字は文字列は存在するが文字数が0の状態です。

たとえば、フォーム入力では次のように考えるとわかりやすいです。

C#
// null: 値そのものが渡されていない
// "": 入力欄はあるが何も入力されていない
// " ": 空白だけ入力されている

実務では、null、空文字、空白だけの文字列をまとめて扱いたい場面がよくあります。

8-4. IsNullOrEmptyの使い方

string.IsNullOrEmptyは、文字列がnullまたは空文字かどうかを判定します。

C#
string text = "";

if (string.IsNullOrEmpty(text))
{
Console.WriteLine("nullまたは空文字です");
}

次のどちらもtrueになります。

C#
string.IsNullOrEmpty(null); // True
string.IsNullOrEmpty(""); // True

ただし、空白だけの文字列はfalseです。

C#
string.IsNullOrEmpty("   "); // False

空白だけの文字列も空として扱いたい場合は、IsNullOrWhiteSpaceを使います。

8-5. IsNullOrWhiteSpaceの使い方

string.IsNullOrWhiteSpaceは、null、空文字、空白だけの文字列を判定できます。

C#
string input = "   ";

if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("入力が空です");
}

次のすべてがtrueになります。

C#
string.IsNullOrWhiteSpace(null);   // True
string.IsNullOrWhiteSpace(""); // True
string.IsNullOrWhiteSpace(" "); // True

ユーザー入力のチェックでは、IsNullOrWhiteSpaceを使うことが多いです。

C#
if (string.IsNullOrWhiteSpace(userName))
{
Console.WriteLine("ユーザー名を入力してください");
}

8-6. null条件演算子を使った安全なアクセス

null条件演算子?.を使うと、nullの可能性があるオブジェクトに安全にアクセスできます。

C#
string text = null;

int? length = text?.Length;

Console.WriteLine(length); // null

textがnullでなければLengthを取得し、nullであれば結果もnullになります。

null合体演算子??と組み合わせると、デフォルト値を指定できます。

C#
string text = null;

int length = text?.Length ?? 0;

Console.WriteLine(length); // 0

文字列がnullの場合でも安全に処理したいときに便利です。

8-7. NullReferenceExceptionを防ぐ実践パターン

NullReferenceExceptionを防ぐには、nullの可能性がある文字列を直接操作しないことが重要です。

悪い例です。

C#
string input = null;

if (input.Length > 0)
{
Console.WriteLine(input);
}

安全な例です。

C#
string input = null;

if (!string.IsNullOrEmpty(input))
{
Console.WriteLine(input);
}

ユーザー入力では、空白だけの文字列も避けたいことが多いため、次のように書くのがおすすめです。

C#
if (!string.IsNullOrWhiteSpace(input))
{
Console.WriteLine(input.Trim());
}
else
{
Console.WriteLine("入力してください");
}

null判定を先に行う習慣をつけると、多くのエラーを防げます。

9. C# stringのフォーマットと表示

9-1. +演算子で文字列を組み立てる

短い文字列であれば、+演算子で組み立てても問題ありません。

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

Console.WriteLine(message);

ただし、変数が増えると読みにくくなります。

C#
string message = "名前: " + name + ", 年齢: " + age + ", 住所: " + address;

このような場合は、文字列補間を使うとすっきり書けます。

9-2. string.Formatの使い方

string.Formatは、プレースホルダーに値を埋め込んで文字列を作る方法です。

C#
string name = "佐藤";
int age = 30;

string message = string.Format("名前は{0}、年齢は{1}歳です。", name, age);

Console.WriteLine(message);

{0}には第1引数、{1}には第2引数が入ります。

現在では文字列補間のほうが読みやすい場面が多いですが、古いコードや共通フォーマットを扱う場面ではstring.Formatを見かけることがあります。

9-3. 文字列補間を使った読みやすい書き方

文字列補間を使うと、変数名をそのまま文字列内に書けます。

C#
string name = "佐藤";
int age = 30;

string message = $"名前は{name}、年齢は{age}歳です。";

string.Formatよりも、どの値がどこに入るのかがわかりやすいです。

式を書くこともできます。

C#
int price = 1000;
int count = 3;

string message = $"合計金額は{price * count}円です。";

実務では、ログ、画面表示、デバッグ出力などで非常によく使われます。

9-4. 数値の桁区切り・小数点表示

文字列補間の中でも書式指定ができます。

C#
int price = 1200000;

string message = $"金額: {price:N0}円";

Console.WriteLine(message); // 金額: 1,200,000円

小数点以下の桁数を指定することもできます。

C#
double value = 123.4567;

Console.WriteLine($"{value:F2}"); // 123.46

パーセント表示もできます。

C#
double rate = 0.1234;

Console.WriteLine($"{rate:P1}"); // 12.3%

数値を見やすく表示したいときに便利です。

9-5. 日付の表示形式を指定する

日付も文字列補間で表示形式を指定できます。

C#
DateTime date = new DateTime(2026, 6, 14);

string text = $"{date:yyyy/MM/dd}";

Console.WriteLine(text); // 2026/06/14

日本語の形式にすることもできます。

C#
string text = $"{date:yyyy年MM月dd日}";
Console.WriteLine(text); // 2026年06月14日

時刻を含める場合は次のように書きます。

C#
DateTime now = DateTime.Now;

Console.WriteLine($"{now:yyyy/MM/dd HH:mm:ss}");

ログ出力や画面表示でよく使う書き方です。

9-6. 複数行の文字列を見やすく書く

複数行の文字列を書く場合は、逐語的文字列リテラルや生文字列リテラルが便利です。

C#
string text = @"1行目
2行目
3行目";

C# 11以降であれば、生文字列リテラルを使うとさらに読みやすく書けます。

C#
string html = """
<div>
<p>Hello</p>
</div>
""";

JSONのようにダブルクォーテーションを多く含む文字列にも向いています。

C#
string json = """
{
"name": "Taro",
"age": 30
}
""";

エスケープを減らすことで、文字列の内容が見やすくなります。

10. C# stringとパフォーマンス

10-1. stringがイミュータブルであることによる影響

C#のstringはイミュータブルです。そのため、文字列を変更するように見える操作でも、実際には新しい文字列が作られます。

C#
string text = "abc";
text = text + "def";

このコードでは、"abcdef"という新しい文字列が作られます。

少ない回数であれば問題になることはほとんどありません。しかし、大量の文字列連結を繰り返すと、多くの一時的な文字列が作られ、メモリや処理速度に影響することがあります。

10-2. ループ内の文字列連結に注意する

ループ内で+を使って文字列を連結し続けると、パフォーマンスが悪くなる場合があります。

C#
string result = "";

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

このコードでは、ループのたびに新しい文字列が作られます。

少ない回数なら問題ありませんが、何千回、何万回と繰り返す場合は、StringBuilderを使うほうが効率的です。

10-3. StringBuilderを使うべきケース

StringBuilderは、文字列を効率よく組み立てるためのクラスです。

C#
using System.Text;

StringBuilder sb = new StringBuilder();

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

string result = sb.ToString();

大量の文字列連結を行う場合や、ループで文字列を少しずつ追加する場合に向いています。

一方、短い文字列を数回連結するだけなら、+や文字列補間で十分です。

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

目的に応じて使い分けることが大切です。

10-4. string.Concat・string.Joinの使いどころ

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

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

Console.WriteLine(result); // ABC

単純な連結であれば、+演算子や文字列補間のほうが読みやすいことも多いです。

string.Joinは、区切り文字を入れて結合したいときに便利です。

C#
string[] items = { "apple", "banana", "orange" };

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

Console.WriteLine(result); // apple, banana, orange

配列やリストの内容をCSV風に出力したいときは、Joinを使うとシンプルに書けます。

10-5. メモリ効率を意識した文字列操作の基本

文字列操作でメモリ効率を意識するには、不要な文字列を何度も作らないことが大切です。

たとえば、ループ内で何度もReplaceSubstringを呼び出す場合、処理量が多くなると負荷が高くなることがあります。

基本的な考え方は次のとおりです。

短い文字列や少ない回数の連結なら、読みやすさを優先して+や文字列補間を使います。

C#
string message = $"{name}さんの得点は{score}点です";

大量の連結なら、StringBuilderを使います。

C#
StringBuilder sb = new StringBuilder();

配列やリストを結合するなら、string.Joinを使います。

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

まずは読みやすいコードを書き、処理が重くなったときに適切な方法へ変更するのが現実的です。

11. C# stringでよくあるエラーと対処法

11-1. NullReferenceExceptionが発生する原因

NullReferenceExceptionは、nullの文字列に対してメソッドやプロパティを呼び出したときに発生します。

C#
string text = null;

// Console.WriteLine(text.Length); // NullReferenceException

対処法は、先にnull判定を行うことです。

C#
if (!string.IsNullOrEmpty(text))
{
Console.WriteLine(text.Length);
}

空白だけの文字列も除外したい場合は、IsNullOrWhiteSpaceを使います。

C#
if (!string.IsNullOrWhiteSpace(text))
{
Console.WriteLine(text.Trim());
}

11-2. IndexOutOfRangeExceptionが発生する原因

文字列の範囲外にアクセスすると、IndexOutOfRangeExceptionが発生します。

C#
string text = "abc";

// Console.WriteLine(text[3]); // エラー

"abc"のインデックスは0、1、2です。3番目は存在しません。

安全にアクセスするには、Lengthを確認します。

C#
if (text.Length > 0)
{
Console.WriteLine(text[0]);
}

最後の文字を取得する場合も、空文字に注意が必要です。

C#
if (!string.IsNullOrEmpty(text))
{
char last = text[text.Length - 1];
Console.WriteLine(last);
}

11-3. 文字列変換でFormatExceptionが出る原因

FormatExceptionは、文字列を数値や日付に変換できないときに発生します。

C#
string input = "abc";

// int number = int.Parse(input); // FormatException

ユーザー入力などでは、必ずTryParseを使うのがおすすめです。

C#
if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値ではありません");
}

日付も同様です。

C#
if (DateTime.TryParse(input, out DateTime date))
{
Console.WriteLine(date);
}
else
{
Console.WriteLine("日付ではありません");
}

11-4. 大文字小文字の違いで比較に失敗する原因

文字列比較では、大文字小文字が違うと一致しません。

C#
string input = "Admin";

Console.WriteLine(input == "admin"); // False

大文字小文字を無視したい場合は、StringComparison.OrdinalIgnoreCaseを使います。

C#
bool result = string.Equals(input, "admin", StringComparison.OrdinalIgnoreCase);

Console.WriteLine(result); // True

ログインID、コマンド、拡張子などを比較する場合は、大文字小文字を区別する必要があるかを考えてから実装しましょう。

11-5. 空白や改行が原因で一致しない場合の対処法

見た目が同じでも、空白や改行が含まれていると文字列は一致しません。

C#
string input = "hello\n";

Console.WriteLine(input == "hello"); // False

前後の空白や改行を取り除くには、Trimを使います。

C#
string input = " hello \n";

string normalized = input.Trim();

Console.WriteLine(normalized == "hello"); // True

ユーザー入力を比較する前には、必要に応じてTrimで整えるとよいでしょう。

C#
if (string.Equals(input.Trim(), "yes", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("はい");
}

12. C# stringの実践サンプル

12-1. 入力文字列が空かチェックする

ユーザー入力が空かどうかをチェックする基本例です。

C#
string input = Console.ReadLine();

if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("入力してください");
}
else
{
Console.WriteLine($"入力内容: {input}");
}

IsNullOrWhiteSpaceを使うことで、未入力、空文字、空白だけの入力をまとめてチェックできます。

12-2. CSV風の文字列を分割する

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

C#
string csv = "apple, banana, orange";

string[] items = csv.Split(',');

foreach (string item in items)
{
Console.WriteLine(item.Trim());
}

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

C#
apple
banana
orange

分割したあとにTrimすることで、余分な空白を取り除けます。

12-3. ファイルパス文字列を扱う

Windowsのファイルパスを書く場合は、逐語的文字列リテラルを使うと読みやすくなります。

C#
string path = @"C:\work\sample.txt";

if (path.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("テキストファイルです");
}

通常の文字列リテラルで書く場合は、バックスラッシュをエスケープする必要があります。

C#
string path = "C:\\work\\sample.txt";

パスを直接連結するより、実際のアプリケーションではPath.Combineを使うほうが安全です。

C#
string folder = @"C:\work";
string file = "sample.txt";

string path = Path.Combine(folder, file);

12-4. ユーザー名やメールアドレスを簡易チェックする

ユーザー名が空でないかチェックする例です。

C#
string userName = " taro ";

if (string.IsNullOrWhiteSpace(userName))
{
Console.WriteLine("ユーザー名を入力してください");
}
else
{
userName = userName.Trim();
Console.WriteLine($"ユーザー名: {userName}");
}

メールアドレスの簡易チェックでは、Containsを使えます。

C#
string email = "sample@example.com";

if (!string.IsNullOrWhiteSpace(email) && email.Contains("@"))
{
Console.WriteLine("メールアドレスの形式に見えます");
}
else
{
Console.WriteLine("メールアドレスを確認してください");
}

ただし、これはあくまで簡易チェックです。厳密なメールアドレス検証が必要な場合は、専用のライブラリやフレームワークの機能を検討しましょう。

12-5. 金額や日付を見やすく表示する

金額を桁区切りで表示する例です。

C#
int price = 1200000;

string message = $"価格: {price:N0}円";

Console.WriteLine(message); // 価格: 1,200,000円

日付を見やすく表示する例です。

C#
DateTime date = new DateTime(2026, 6, 14);

string text = $"日付: {date:yyyy年MM月dd日}";

Console.WriteLine(text); // 日付: 2026年06月14日

数値や日付は、表示形式を指定することでユーザーにわかりやすく伝えられます。

12-6. 検索キーワードに一致する文字列を探す

検索キーワードが文字列に含まれるかを判定する例です。

C#
string text = "C# stringの使い方を学びます";
string keyword = "STRING";

if (text.Contains(keyword, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("キーワードが見つかりました");
}
else
{
Console.WriteLine("見つかりませんでした");
}

StringComparison.OrdinalIgnoreCaseを指定することで、大文字小文字を無視して検索できます。

リストの中から一致する文字列を探す例です。

C#
List<string> titles = new List<string>
{
"C# string入門",
"LINQの基本",
"ASP.NET Coreの使い方"
};

string keyword = "string";

foreach (string title in titles)
{
if (title.Contains(keyword, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(title);
}
}

13. C# stringのおすすめの使い方・ベストプラクティス

13-1. null判定はIsNullOrEmpty・IsNullOrWhiteSpaceを使う

nullや空文字の判定では、string.IsNullOrEmptystring.IsNullOrWhiteSpaceを使うと安全です。

C#
if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("入力が空です");
}

ユーザー入力では、空白だけの文字列も無効にしたいことが多いため、IsNullOrWhiteSpaceが特に便利です。

C#
if (!string.IsNullOrWhiteSpace(input))
{
string value = input.Trim();
}

直接input.Lengthを呼ぶ前に、nullの可能性がないかを確認しましょう。

13-2. 比較ではStringComparisonを明示する

文字列比較では、可能な限りStringComparisonを明示しましょう。

C#
bool result = string.Equals(a, b, StringComparison.Ordinal);

大文字小文字を無視する場合は次のように書きます。

C#
bool result = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

ContainsStartsWithEndsWithでも指定できます。

C#
if (fileName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("テキストファイルです");
}

比較ルールを明確にすることで、予期しない不具合を防ぎやすくなります。

13-3. 文字列連結は用途に応じて使い分ける

文字列連結は、用途に応じて使い分けるのが大切です。

短い文章なら文字列補間が読みやすいです。

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

配列やリストを区切り文字で結合するなら、string.Joinが便利です。

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

大量の文字列をループで組み立てるなら、StringBuilderを使います。

C#
StringBuilder sb = new StringBuilder();

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

読みやすさと効率のバランスを考えて選びましょう。

13-4. 変換処理ではTryParseを優先する

文字列を数値や日付に変換するときは、TryParseを優先しましょう。

C#
if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値ではありません");
}

Parseは変換できない場合に例外が発生します。ユーザー入力や外部データでは、正しい値が入っているとは限りません。

C#
if (DateTime.TryParse(input, out DateTime date))
{
Console.WriteLine(date);
}

安全に処理できるコードを書くためにも、TryParseはよく使うパターンとして覚えておきましょう。

13-5. 読みやすさを重視して文字列補間を使う

変数を含む文字列を作る場合は、文字列補間を使うと読みやすくなります。

C#
string message = $"名前: {name}, 年齢: {age}";

+で連結するより、完成形の文章をイメージしやすくなります。

C#
string message = "名前: " + name + ", 年齢: " + age;

特に、ログや画面表示のメッセージでは文字列補間が便利です。

C#
Console.WriteLine($"処理件数: {count}件");

13-6. 文化依存の比較・変換に注意する

文字列比較や数値・日付の変換では、文化依存の影響を受ける場合があります。

たとえば、日付の書式は国や地域によって異なります。

C#
// 2026/06/14
// 06/14/2026
// 14/06/2026

内部的なIDやキーの比較では、文化に依存しないStringComparison.Ordinalを使うのが基本です。

C#
string.Equals(key1, key2, StringComparison.Ordinal);

ユーザーに表示する文字列と、プログラム内部で判定する文字列は、目的を分けて考えることが大切です。

14. C# stringに関するよくある質問

14-1. stringとStringはどちらを使うべき?

通常のC#コードでは、stringを使うのがおすすめです。

C#
string text = "hello";

stringSystem.Stringの別名なので、機能的には同じです。

C#
System.String text = "hello";

C#の基本型としての見た目をそろえる意味でも、stringを使うことが一般的です。

14-2. string.Emptyと""はどちらがよい?

string.Empty""は、どちらも空文字を表します。

C#
string a = string.Empty;
string b = "";

実用上、大きな違いはありません。

読みやすさを重視するなら、チームのルールに合わせるのが一番です。個人で書く場合は、短く直感的な""でも問題ありません。

14-3. stringはなぜ参照型なのに==で比較できる?

stringでは、==演算子が文字列の内容を比較するように定義されているためです。

C#
string a = "hello";
string b = "hello";

Console.WriteLine(a == b); // True

そのため、参照型でありながら、値のような感覚で比較できます。

ただし、比較ルールを明確にしたい場合は、string.EqualsStringComparisonを指定する方法がおすすめです。

C#
string.Equals(a, b, StringComparison.Ordinal);

14-4. nullと""は同じ?

null""は同じではありません。

C#
string a = null;
string b = "";

Console.WriteLine(a == b); // False

nullは文字列が存在しない状態です。""は文字列は存在するが、中身が空の状態です。

nullと空文字をまとめて判定したい場合は、string.IsNullOrEmptyを使います。

C#
if (string.IsNullOrEmpty(text))
{
Console.WriteLine("nullまたは空文字です");
}

空白だけの文字列も含めたい場合は、string.IsNullOrWhiteSpaceを使います。

14-5. 文字列の比較でEqualsと==はどちらを使う?

単純な比較であれば、==でも問題ありません。

C#
if (a == b)
{
Console.WriteLine("一致しました");
}

ただし、null安全に比較したい場合や、大文字小文字を無視したい場合は、string.Equalsがおすすめです。

C#
bool result = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

実務では、比較の意図を明確にするために、StringComparisonを指定したstring.Equalsを使うと安心です。

14-6. StringBuilderはいつ使うべき?

StringBuilderは、大量の文字列を繰り返し連結する場合に使います。

C#
StringBuilder sb = new StringBuilder();

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

string result = sb.ToString();

短い文字列を数回連結するだけなら、文字列補間や+演算子で十分です。

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

目安として、ループの中で何度も文字列を追加するならStringBuilderを検討しましょう。

まとめ

C#のstringは、文字列を扱うための基本的な型です。画面表示、入力チェック、ファイルパス、検索、ログ、データ変換など、さまざまな場面で使います。

まず押さえておきたいポイントは、stringSystem.Stringの別名であり、参照型でありながら値のように扱えることです。また、stringはイミュータブルな型なので、置換や連結を行うと新しい文字列が作られます。

文字列操作では、LengthSubstringContainsReplaceTrimSplitJoinなどをよく使います。比較では、==Equalsだけでなく、StringComparisonを指定することが重要です。

変換処理では、ParseよりもTryParseを優先すると、エラーに強いコードになります。nullや空文字の判定では、IsNullOrEmptyIsNullOrWhiteSpaceを使うことで、NullReferenceExceptionを防ぎやすくなります。

C# stringを正しく理解すると、日常的なプログラミングの多くがスムーズになります。まずは基本操作、比較、変換、null判定をしっかり身につけ、実際のコードで少しずつ使い慣れていきましょう。