C#を用いたシステム開発において、同じ処理を何度も繰り返す「ループ処理」は欠かせない要素の一つです。

その中でも while 文は、「特定の条件が満たされている間、処理を繰り返す」という非常にシンプルかつ強力な制御構造を持っています。

配列の要素を順番に処理するだけでなく、ユーザーの入力を待ち続けたり、特定のフラグが書き換わるまで待機したりするなど、その用途は多岐にわたります。

本記事では、C#における while 文の基本的な使い方から、実戦で役立つ応用テクニック、さらには do-while 文との違いや注意点まで、プロの視点で徹底的に解説します。

while文の基本構造と動作原理

C#の while 文は、指定した条件式が true である限り、ブロック内のコードを実行し続けるループ機構です。

まずは、最も基本的な構文を確認しましょう。

C#
while (条件式)
{
    // 条件式がtrueの間、繰り返し実行される処理
}

この構造において最も重要な点は、「ループの開始前に条件判定が行われる」という点です。

これを「前判定ループ」と呼びます。

もし最初に条件式を評価した時点で false であった場合、ループ内の処理は一度も実行されません。

基本的なカウントアップの例

具体的なコードを見てみましょう。

以下のプログラムは、変数 i が5未満の間、その値をコンソールに出力し続ける例です。

C#
using System;

class Program
{
    static void Main()
    {
        int i = 0;

        // iが5より小さい間、ループを継続する
        while (i < 5)
        {
            Console.WriteLine($"現在の値は {i} です。");
            
            // カウンタをインクリメントしないと無限ループになるので注意
            i++;
        }

        Console.WriteLine("ループが終了しました。");
    }
}
実行結果
現在の値は 0 です。
現在の値は 1 です。
現在の値は 2 です。
現在の値は 3 です。
現在の値は 4 です。
ループが終了しました。

この例では、i++ という記述が非常に重要です。

もしこの記述を忘れてしまうと、i の値は永久に 0 のままとなり、条件式 i < 5 は常に true を返し続けます。

これが「無限ループ」と呼ばれる状態であり、プログラムがフリーズする原因となります。

do-while文との違い:実行タイミングの重要性

while 文とセットで語られることが多いのが do-while 文です。

どちらも条件によって繰り返しを行いますが、「最初の1回を実行するかどうか」という点で決定的な違いがあります。

do-while文の構文

C#
do
{
    // 最低でも1回は実行される処理
} while (条件式);

do-while 文は「後判定ループ」と呼ばれ、ループ内の処理を実行した後に条件式を評価します。

そのため、たとえ最初から条件が false であっても、必ず1回は処理が実行されるのが特徴です。

動作の比較

以下のコードで、条件が最初から満たされていない場合の挙動の違いを確認してください。

C#
using System;

class Program
{
    static void Main()
    {
        int value = 10;

        Console.WriteLine("--- while文の開始 ---");
        while (value < 5)
        {
            // 条件 (10 < 5) は最初からfalseなので実行されない
            Console.WriteLine("whileの中を通りました。");
        }

        Console.WriteLine("--- do-while文の開始 ---");
        do
        {
            // 条件判定の前に1回実行される
            Console.WriteLine("do-whileの中を通りました。");
        } while (value < 5);
    }
}
実行結果
--- while文の開始 ---
--- do-while文の開始 ---
do-whileの中を通りました。

このように、ユーザーに最低1回はメニューを表示したい場合や、リトライ処理などで「まず試行してから結果を確認したい」という場合には do-while が適しています。

一方で、データの個数が0個のときには何もしたくないといった一般的なケースでは while を使用するのが定石です。

ループ制御:breakとcontinueの活用

ループの途中で処理を中断したり、次の繰り返しへスキップしたりしたい場合には、break 文と continue 文を使用します。

break文によるループの脱出

break は、その行が実行された瞬間にループを強制終了させ、ブロックの外へ制御を移します。

特定の条件に合致したときに探索を止めたい場合などに多用されます。

C#
using System;

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

        while (true) // 意図的な無限ループ
        {
            if (count >= 3)
            {
                Console.WriteLine("countが3になったのでループを抜けます。");
                break; // ループを終了
            }
            Console.WriteLine($"count = {count}");
            count++;
        }
    }
}

continue文による処理のスキップ

continue は、現在の回の残り処理をスキップし、即座に次の条件判定(whileの先頭)へ戻るための命令です。

特定の条件のときだけ処理を除外したい場合に便利です。

C#
using System;

class Program
{
    static void Main()
    {
        int i = 0;
        while (i < 5)
        {
            i++;
            if (i % 2 == 0)
            {
                // 偶数の場合はこれ以降の処理を飛ばして次の判定へ
                continue;
            }
            Console.WriteLine($"奇数を発見: {i}");
        }
    }
}
実行結果
奇数を発見: 1
奇数を発見: 3
奇数を発見: 5

continue を使用する際の注意点として、カウンタ変数(上記の例では i++)の更新場所があります。

もし continue の後に更新処理を書いてしまうと、その処理が飛ばされて無限ループに陥るリスクがあるため、ループの先頭付近で更新を行うなどの工夫が必要です。

while文とfor文の使い分け

C#には、もう一つの強力なループ文として for 文が存在します。

これらはどのように使い分けるべきでしょうか。

特徴while文for文
主な用途繰り返す回数が不明な場合繰り返す回数が決まっている場合
終了条件真偽値(bool)の状態に依存カウンタ変数による範囲指定
可読性シンプルな条件監視に向く配列やリストの全要素参照に向く

一般的に、「10回繰り返す」「このリストの要素数分だけ処理する」というケースでは for 文や foreach 文が適しています。

なぜなら、初期化・条件・更新が一箇所にまとまっており、バグが入り込みにくいからです。

一方で、「ネットワークの受信を待つ」「ファイルが読み終わるまで繰り返す」「有効なユーザー入力が得られるまで聞き直す」といった、いつ終わるか事前には分からないケースでは while 文が最もその真価を発揮します。

実践的な応用例:ユーザー入力のバリデーション

実際のアプリケーション開発でよく見られる while 文の利用シーンとして、ユーザーからの入力チェック(バリデーション)があります。

正しい値が入力されるまで、何度でも入力を促す処理です。

C#
using System;

class Program
{
    static void Main()
    {
        bool isValidInput = false;
        int age = 0;

        while (!isValidInput)
        {
            Console.Write("年齢を入力してください(0以上の数値): ");
            string input = Console.ReadLine();

            // 数値に変換できるか、かつ0以上であるかをチェック
            if (int.TryParse(input, out age) && age >= 0)
            {
                isValidInput = true; // 条件を満たしたのでループ終了へ
            }
            else
            {
                Console.WriteLine("エラー: 正しい数値を入力してください。");
            }
        }

        Console.WriteLine($"登録された年齢は {age} 歳です。");
    }
}

このように、bool 型のフラグ変数(上記の例では isValidInput)を用意してループを制御する手法は、複雑な業務ロジックにおいても頻繁に使用されるパターンです。

無限ループの活用と回避策

「無限ループ」はプログラムをフリーズさせる危険なものとして扱われることが多いですが、意図的に利用される場面もあります。

例えば、サーバープログラム、ゲームのメインループ、OSのタスクスケジューラなどは、常に動き続ける必要があるため while (true) で記述されます。

安全な無限ループの書き方

無限ループを作成する場合でも、必ず内部で「終了条件(Exit Condition)」を設け、break で抜け出せるように設計するのがプロの書き方です。

C#
while (true)
{
    // 何らかの主要な処理
    ProcessTask();

    // 終了命令を受け取ったらループを抜ける
    if (CheckExitSignal())
    {
        break;
    }

    // CPU負荷を抑えるための待機(重要)
    System.Threading.Thread.Sleep(10); 
}

特にデスクトップアプリやサービス開発において、何も待機処理を入れずに無限ループを回すと、CPU使用率が100%に張り付いてしまう可能性があります。

Thread.Sleep や、非同期処理であれば Task.Delay を適切に組み合わせて、リソースを効率的に使用するように心がけましょう。

while文におけるよくあるミスと注意点

1. 条件式の評価ミス

ループが一度も実行されない、あるいは逆に終わらない原因の多くは、条件式の論理ミスです。

例えば、i < 10 と書くべきところを i > 10 と書いてしまうようなミスです。

境界値(この場合は10を含むか含まないか)についても、テスト時に注意深く確認する必要があります。

2. 変数の更新忘れ

先述の通り、ループ内で条件に関わる変数を更新し忘れると無限ループが発生します。

特に複雑な if 文による分岐がある場合、特定のパスを通った時だけ更新が漏れてしまうといったバグが発生しやすいです。

3. 浮動小数点数(double/float)の比較

while 文の条件式で double 型などの浮動小数点数を使用するのは避けるべきです。

計算誤差により、期待した値と完全に一致せず、ループが終了しない可能性があるためです。

繰り返し回数の制御には、必ず整数型(intlong)を使用しましょう。

パフォーマンスとメモリに関する考察

C#の while 文自体は非常に低レベルな命令にコンパイルされるため、実行速度におけるオーバーヘッドはほとんどありません。

しかし、ループ内で行う処理の内容によってはパフォーマンスに大きな影響を与えます。

ループ内でのアロケーション

ループの中で頻繁に new を行い、インスタンスを生成すると、ガベージコレクション(GC)の負荷が高まります。

可能な限り、ループの外でオブジェクトを再利用するか、構造体(struct)や Span<T> を活用してメモリ効率を高めることが、現代的なC#開発では求められます。

非同期ループの活用

I/O処理(ファイル読み書きや通信)を含むループの場合、while 文の中で同期的な待機を行うと、スレッドをブロックしてしまいます。

これを防ぐために、モダンなC#では await を組み合わせた非同期ループが推奨されます。

C#
// ネットワークストリームからデータを読み取リ続ける例
while (true)
{
    var data = await reader.ReadLineAsync();
    if (data == null) break;
    
    ProcessData(data);
}

このように記述することで、データの到着を待っている間、スレッドを他の処理に解放することができ、アプリケーション全体のレスポンスを向上させることができます。

まとめ

C#の while 文は、プログラムに柔軟な繰り返し処理をもたらす基礎的なツールです。

  • while文:実行前に条件を判定する「前判定ループ」。回数が決まっていない繰り返しに最適。
  • do-while文:実行後に条件を判定する「後判定ループ」。最低1回は必ず実行したい場合に利用。
  • 制御命令break で脱出、continue で次の回へスキップ。
  • 注意点:無限ループの防止、変数の更新、およびCPU負荷への配慮が必要。

プログラミング初心者の方は、まず while 文を使って「何かが起こるまで待機する」ようなシンプルなロジックを書いてみることから始めましょう。

基本をマスターすれば、より複雑な非同期処理や大規模なシステム構築においても、確実な制御フローを設計できるようになります。

ループ処理を正しく理解し、効率的でバグのないコードを目指しましょう。