C#でプログラミングを行っていると、ユーザー入力のゆらぎを吸収したり、検索処理を実装したりする際に、文字列の大文字・小文字を統一したい場面が多々あります。
C#には非常に便利なToUpperメソッドやToLowerメソッドが用意されており、これらを使うことで直感的に文字列の変換が可能です。
しかし、単純な変換だけではなく、国際化(グローバル化)を考慮した挙動や、パフォーマンスを意識した使い方を知っておくことは、プロフェッショナルな開発において欠かせません。
本記事では、基本的な使い方から応用的なテクニックまで、詳しく解説していきます。
C#における大文字・小文字変換の基本
C#の文字列(string)は不変(イミュータブル)なオブジェクトです。
そのため、変換メソッドを呼び出しても元の文字列が書き換わるのではなく、変換後の新しい文字列が返されるという性質をまず理解しておく必要があります。
ToUpperメソッドとToLowerメソッドの概要
もっとも一般的に使われるのが、すべての文字を大文字にするToUpper()と、小文字にするToLower()です。
これらはSystem.Stringクラスのインスタンスメソッドとして定義されています。

基本的なサンプルコード
まずは、もっともシンプルな変換の例を見てみましょう。
using System;
class Program
{
static void Main()
{
// 元の文字列を定義
string originalText = "C# Programming Is Fun!";
// すべて大文字に変換
string upperText = originalText.ToUpper();
// すべて小文字に変換
string lowerText = originalText.ToLower();
// 結果を出力
Console.WriteLine("元の文字列: " + originalText);
Console.WriteLine("大文字変換: " + upperText);
Console.WriteLine("小文字変換: " + lowerText);
}
}
元の文字列: C# Programming Is Fun!
大文字変換: C# PROGRAMMING IS FUN!
小文字変換: c# programming is fun!
このコードからわかるように、アルファベット以外の記号(#)やスペースなどは変換の影響を受けません。
注意点:元の文字列は変化しない
初心者の方がよく陥るミスとして、戻り値を受け取らずに「text.ToUpper();」とだけ記述してしまうパターンがあります。
前述の通り、C#の文字列は書き換えができないため、戻り値を変数に代入するか、そのままメソッドの引数に渡す必要があります。
国際化を考慮した変換(InvariantCulture)
グローバルに展開するアプリケーションを開発する場合、実行環境の「カルチャ(言語や地域の情報)」によって大文字・小文字の変換ルールが異なる場合があることに注意しなければなりません。
なぜカルチャを気にする必要があるのか
もっとも有名な例はトルコ語です。
トルコ語では、アルファベットの「i」の大文字は「İ」(点付きのI)であり、「I」の小文字は「ı」(点なしのi)となります。

ToUpperInvariantとToLowerInvariant
システムの内部的な処理(IDの照合、ファイルパスの処理、通信プロトコルの解析など)で大文字・小文字を変換したい場合は、実行環境の言語設定に左右されないToUpperInvariant()またはToLowerInvariant()を使用するのがベストプラクティスです。
using System;
using System.Globalization;
class Program
{
static void Main()
{
string text = "i";
// 現在のカルチャをトルコ語に設定(シミュレーション)
CultureInfo.CurrentCulture = new CultureInfo("tr-TR");
// 通常のToUpper(実行環境の影響を受ける)
Console.WriteLine("通常変換: " + text.ToUpper());
// インバリアント・カルチャでの変換(言語に依存しない)
Console.WriteLine("不変変換: " + text.ToUpperInvariant());
}
}
通常変換: İ
不変変換: I
このように、ToUpperInvariantを使用することで、どの国のコンピュータで実行しても常に同じ結果を得ることができます。
文字列比較における大文字・小文字の無視
「ユーザーが入力した文字列が特定のキーワードと一致するか」を判定する場合、一度ToLowerで変換してから比較するという手法がよく取られます。
しかし、これはパフォーマンスと正確性の観点から推奨されません。
変換してからの比較は非効率
文字列を変換すると、新しいメモリ領域が確保(アロケーション)されます。
ループの中で大量の比較を行う場合、このメモリ確保がパフォーマンスの低下やGC(ガベージコレクション)の負荷増大を招きます。

推奨される比較方法:String.Equals
C#では、String.Equalsメソッドの引数にStringComparison列挙型を指定することで、変換を挟まずに大文字・小文字を無視した比較が可能です。
using System;
class Program
{
static void Main()
{
string input = "User_Input";
string target = "user_input";
// 推奨される方法: 大文字小文字を無視して比較
bool isEqual = string.Equals(input, target, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("一致するか: " + isEqual);
}
}
一致するか: True
この方法であれば、余計な文字列インスタンスを生成しないため、効率的かつ安全に比較処理が行えます。
高度な変換:Span<T>を利用したメモリ効率の最適化
最新のC#(.NET 5以降)では、非常に大きな文字列を扱ったり、高頻度で変換を行ったりする場合に、Span<char>を使用してメモリ割り当てを極限まで抑える手法が使われることがあります。
破壊的な変換(バッファへの書き込み)
通常、文字列は変更できませんが、スタック領域や既存の配列をSpanとして扱うことで、その領域内で文字を直接変換できます。
using System;
class Program
{
static void Main()
{
string source = "Advanced C# Techniques";
// 1. 読み取り元のSpan(ReadOnlySpan<char>)
ReadOnlySpan<char> sourceSpan = source.AsSpan();
// 2. 書き込み先のバッファをスタックに確保(元の長さ分)
Span<char> destination = stackalloc char[sourceSpan.Length];
// 3. MemoryExtensions のメソッドを呼び出す
// 引数は (読み取り元, 書き込み先)
MemoryExtensions.ToUpperInvariant(sourceSpan, destination);
// 結果の確認
Console.WriteLine(destination.ToString());
}
}
このようにMemoryExtensionsを使用すると、既存のバッファに対して直接変換結果を書き込むことができるため、大量の文字列変換が必要なバックエンドシステムやゲーム開発などで威力を発揮します。
特定の文字のみを変換する場合
文字列全体ではなく、1文字(char型)だけを変換したい場合は、char.ToUpperやchar.ToLowerを使用します。
char型の変換メソッド
using System;
class Program
{
static void Main()
{
char initial = 'a';
// 1文字だけ大文字に変換
char upperInitial = char.ToUpper(initial);
Console.WriteLine(upperInitial); // 出力: A
}
}
これを利用して、「文字列の先頭だけを大文字にする(キャピタライズ)」といった処理も自作できます。
先頭文字だけ大文字にする例
public static string Capitalize(string input)
{
if (string.IsNullOrEmpty(input)) return input;
// 先頭を大文字、残りをそのまま結合
return char.ToUpper(input[0]) + input.Substring(1);
}
大文字・小文字変換の使い分けまとめ
変換メソッドにはいくつかの種類があるため、状況に応じて適切なものを選択することが重要です。
以下の表に主なメソッドの使い分けをまとめました。
| メソッド名 | 主な用途 | 特徴 |
|---|---|---|
ToUpper() | 画面表示用の一般的な変換 | 実行環境(カルチャ)に依存する |
ToLower() | 画面表示用の一般的な変換 | 実行環境(カルチャ)に依存する |
ToUpperInvariant() | システム内部の処理・照合 | 言語設定に関わらず常に一定の結果を返す |
ToLowerInvariant() | システム内部の処理・照合 | 言語設定に関わらず常に一定の結果を返す |
String.Equals(...) | 一致判定のみが必要な場合 | 新しい文字列を生成しないため高速 |

まとめ
C#での大文字・小文字変換は、非常にシンプルに扱える一方で、奥の深いテーマでもあります。
日常的なプログラミングではToUpperやToLowerで十分なケースが多いですが、「カルチャ(文化圏)への配慮」と「パフォーマンス(メモリ効率)」の2点を意識できるようになると、コードの品質は一段上のレベルへと引き上がります。
特に、検索やフィルタリングのロジックでToLower().Contains()のように書いている箇所があれば、本記事で紹介したStringComparisonを利用した比較に書き換えることを検討してみてください。
それだけで、バグに強く、動作の軽いアプリケーションに近づけることができます。
この記事を参考に、適切な文字列操作をマスターしましょう。
