C#におけるプログラム制御の基本中の基本であり、最も頻繁に使用される構文の一つがif文です。
プログラムは、与えられたデータやユーザーの操作に応じて、実行する処理を切り替える必要があります。
この「条件に応じた分岐」を実現するのがif文の役割です。
本記事では、初心者の方が躓きやすい基本文法から、実務で役立つ応用的な書き方、さらには近年のC#アップデートで導入された高度なパターンマッチングまで、徹底的に解説します。
この記事を読み終える頃には、複雑な条件分岐も迷わず実装できるようになっているでしょう。
if文の基本構造と書き方
C#のif文は、指定した条件式が真(true)であるか偽(false)であるかによって、次に実行するコードブロックを決定します。
最もシンプルな形式は、条件が成立したときだけ特定の処理を行うものです。
基本的な構文
if文の後に続くカッコ () 内に、結果が bool 型(true または false)になる条件式を記述します。
using System;
class Program
{
static void Main()
{
int score = 85;
// scoreが80以上の場合にメッセージを表示する
if (score >= 80)
{
Console.WriteLine("合格です!素晴らしい成績ですね。");
}
}
}
合格です!素晴らしい成績ですね。
この例では、score >= 80 という条件が評価されます。
変数の値が85であるため、この式は true となり、中カッコ {} 内の処理が実行されます。
もし値が70であれば、何も表示されずにプログラムは終了します。
コードブロックと波括弧の省略について
C#では、if文の対象となる処理が 1行(1つの文)のみの場合、波括弧 { } を省略することが可能です。
しかし、可読性やメンテナンス性の観点から、基本的には省略せずに記述することが推奨されます。
後から処理を追加した際に、波括弧がないことで意図しない動作(2行目がif文の範囲外になる)を引き起こすバグを防ぐためです。
else句とelse if句による複数分岐
単一の条件だけでなく、「そうでなかった場合の処理」や「別の条件に合致する場合の処理」を記述することで、より複雑なロジックを組み立てることができます。
else句:条件が成立しなかった場合の処理
else を使用すると、if文の条件が false だったときに実行されるブロックを定義できます。
int age = 15;
if (age >= 18)
{
Console.WriteLine("成人です。");
}
else
{
Console.WriteLine("未成年です。");
}
未成年です。
else if句:複数の条件を順番に判定する
3つ以上の分岐を作りたい場合は、else if を組み合わせて使用します。
判定は上から順番に行われ、最初に条件が一致したブロックだけが実行される点に注意してください。
int temperature = 25;
if (temperature >= 30)
{
Console.WriteLine("暑いですね。熱中症に注意してください。");
}
else if (temperature >= 20)
{
Console.WriteLine("過ごしやすい気候です。");
}
else if (temperature >= 10)
{
Console.WriteLine("少し肌寒いですね。");
}
else
{
Console.WriteLine("寒いです。防寒対策をしてください。");
}
過ごしやすい気候です。
この例では、25度は「30以上」ではないため次の判定に移り、「20以上」に該当するためそのブロックが実行されます。
その後の「10以上」という条件も論理的には満たしていますが、既に上の条件で一致しているため無視されます。
比較演算子と論理演算子の活用
if文の条件式を正しく記述するためには、比較演算子と論理演算子の理解が不可欠です。
これらを組み合わせることで、精緻な条件指定が可能になります。
主要な比較演算子
値を比較するために使用される演算子を以下の表にまとめました。
| 演算子 | 意味 | 使用例 |
|---|---|---|
== | 等しい | a == b |
!= | 等しくない | a != b |
> | より大きい | a > b |
< | より小さい | a < b |
>= | 以上 | a >= b |
<= | 以下 | a <= b |
注意点として、等しいことを示す演算子は == (イコール2つ)です。
数学のように = と書いてしまうと、C#では代入演算子とみなされ、コンパイルエラーの原因となります。
論理演算子による複数条件の結合
「AかつB」や「AまたはB」といった複雑な条件は、論理演算子を使って表現します。
- AND演算子 (
&&): 両方の条件が真のときに真。 - OR演算子 (
||): 少なくとも片方の条件が真のときに真。 - NOT演算子 (
!): 条件の真偽を反転させる。
int hour = 14;
bool isWeekday = true;
// 平日の9時から17時までの間かどうかを判定
if (isWeekday && (hour >= 9 && hour < 17))
{
Console.WriteLine("業務時間内です。");
}
業務時間内です。
短絡評価(ショートサーキット評価)という特性についても覚えておきましょう。
&& の場合、左側の条件が false であれば、右側の条件は評価されません。
同様に || の場合、左側が true であれば右側は評価されません。
これは、右側の評価に負荷がかかる処理や、nullチェックを伴う処理を行う際に非常に重要です。
条件分岐をスッキリさせる三項演算子
if文をより簡潔に記述する方法として、条件演算子(三項演算子)があります。
これは、条件によって変数に代入する値を切り替える際などに非常に便利です。
三項演算子の構文
条件式 ? 真の場合の値 : 偽の場合の値
int score = 45;
// if-elseを使わずに1行で記述可能
string result = (score >= 60) ? "合格" : "不合格";
Console.WriteLine($"判定結果: {result}");
判定結果: 不合格
三項演算子はコードを短くできますが、複雑な条件を詰め込みすぎると可読性が著しく低下するため、単純な代入やリターン時のみに使用するのがベストプラクティスです。
ネストの回避とガード句(Early Return)
if文の中にさらにif文を書くことを「ネスト(入れ子)」と呼びます。
ネストが深くなると、コードの構造を把握するのが難しくなり、バグの温床となります。
深いネストの例(避けるべきコード)
void ProcessOrder(Order order)
{
if (order != null)
{
if (order.IsActive)
{
if (order.Items.Count > 0)
{
// 本来やりたい処理
Console.WriteLine("注文を処理します。");
}
}
}
}
このようなコードは、ガード句(Early Return)を用いることで劇的に改善できます。
ガード句によるリファクタリング
ガード句とは、メソッドの冒頭で「処理を続行できない条件」を判定し、早々に return させてしまう手法です。
void ProcessOrder(Order order)
{
// 条件を満たさない場合は先に抜ける
if (order == null) return;
if (!order.IsActive) return;
if (order.Items.Count == 0) return;
// メインの処理をネストなしで記述できる
Console.WriteLine("注文を処理します。");
}
この書き方を採用することで、「何が正常系で、何が例外的なケースか」が明確になり、コードの品質が向上します。
モダンC#のパターンマッチング
近年のC#(C# 7.0以降)では、if文と組み合わせて使用できる強力なパターンマッチング機能が次々と追加されています。
これにより、型の判定やプロパティの比較がより直感的に行えるようになりました。
型パターンの利用
is 演算子を使用して、型を判定しながら同時に変数へ割り当てることができます。
object data = "こんにちは、C#の世界へ!";
if (data is string text)
{
// text変数はこのブロック内でstring型として利用可能
Console.WriteLine($"文字列の長さは {text.Length} です。");
}
プロパティパターン(C# 8.0以降)
オブジェクトのプロパティを直接参照して条件判定を行うことができます。
var user = new { Name = "田中", Age = 25, IsAdmin = true };
if (user is { IsAdmin: true, Age: >= 20 })
{
Console.WriteLine($"{user.Name}さんは成人管理者です。");
}
論理パターン(C# 9.0以降)
and, or, not といったキーワードを使って、より自然言語に近い形で条件を記述できます。
従来の && や || とも併用可能ですが、パターンマッチング内ではこれらのキーワードが威力を発揮します。
int temperature = 25;
// notキーワードを使った直感的な判定
if (temperature is not 0)
{
Console.WriteLine("温度は0ではありません。");
}
// 範囲指定もスッキリ書ける
if (temperature is >= 10 and <= 30)
{
Console.WriteLine("適温です。");
}
実践的な活用シーン:Null合体演算子との組み合わせ
実務では、変数が null かどうかをif文でチェックする場面が非常に多いです。
C#にはこれらを簡略化する便利な演算子が備わっています。
Null許容型とif文
string? userName = GetNameFromDatabase();
// 従来の書き方
if (userName == null)
{
userName = "ゲスト";
}
// Null合体代入演算子 (??=) を使った書き方
userName ??= "ゲスト";
Console.WriteLine($"ようこそ、{userName}さん。");
??= は、左辺が null のときのみ右辺の値を代入します。
if文で行っていた冗長なnullチェックを1行に集約でき、本来注目すべきロジックに集中できるようになります。
if文をいつ使うべきか:switch文との使い分け
条件分岐にはif文の他に switch 文(またはswitch式)があります。
これらをどう使い分けるべきでしょうか。
- if文が適している場合
次の場合に
ifを使うのが適切です:- switch文(式)が適している場合
次の場合に
switchを使うのが適切です:
特にC# 8.0以降の switch式 は非常に強力で、if-else ifの羅列を劇的にクリーンにできるため、積極的に活用を検討しましょう。
まとめ
C#のif文は、単純な真偽判定から始まり、論理演算子による複合条件、そして最新のパターンマッチングへと進化してきました。
基本的な使い方をマスターすることはもちろん大切ですが、実務においては「いかにネストを浅く保つか」「いかに読みやすく簡潔に書くか」という点も同様に重要です。
本記事で紹介した以下のポイントを意識して、日々のコーディングに取り組んでみてください。
- 基本:
if,else if,elseを正しく使い分ける。 - 効率化: 三項演算子や論理演算子を使って記述を簡略化する。
- 可読性: ガード句(Early Return)を活用してネストを深くしない。
- 最新機能:
is演算子やパターンマッチング(and,or,not)を取り入れる。
条件分岐を制する者は、プログラムの制御を制します。
基本をしっかりと固め、状況に応じた最適な書き方を選択できるようになりましょう。






