第11章:ガード節の書き方:読みやすさの型を作る🛡️📐

ガード節には、「読みやすさの王道パターン(型)」 があるよ✨
- 「入口で弾く」コードを読みやすく統一できるようになる😊🧹
- 例外の種類(
ArgumentNullException/ArgumentException/ArgumentOutOfRangeExceptionなど)を迷わず選べるようになる🎁✅ - .NET 10 / C# 14の“ThrowIf 系”を使って、短く安全なガード節を書けるようになる🚀💻 (Microsoft Learn)
1. ガード節ってなに?🛡️📐

「ガード節(Guard Clause)」 は、メソッドのいちばん最初(入口)で 不正な値を弾いてしまう書き方のことだよ🛡️✨ ガード節(guard clause)は、メソッドの冒頭で 「この条件だと処理できないよ!」を先に弾いて、下の本体をスッキリさせる書き方だよ✨
- ✅ 契約(Pre条件)をコードで強制できる🤝📝
2. “読みやすいガード節”の基本形(型)🎀
ガード節は、だいたいこの並びにすると超読みやすいよ😊✨
✅ 型:上から順に「軽い・単純・重要」へ🪜
- 状態(this側)の前提(Dispose済み等)🏠⚠️
3. 例外は何を投げる?ミニ辞書📚✨
ここがブレると、チームのコードが読みにくくなるよ〜🥺💦 まずは“鉄板”だけ覚えよう💪🌸
ArgumentNullException:引数がnull🕳️ArgumentException:引数の内容がダメ(空、形式違い、関係違いなど)🧩ArgumentOutOfRangeException:引数が範囲外(負、上限超えなど)📉📈InvalidOperationException:オブジェクト状態がダメ(順序違い、初期化前など)🚫ObjectDisposedException:破棄済みで使えない🗑️
4. .NET 10 世代の「ThrowIf」でガード節を短くする💨✨
4.1 null チェックはこれでOK🕳️✅
public void Save(Customer customer)
{
ArgumentNullException.ThrowIfNull(customer);
// ↓ここから本体(前提を信じてOK)
}
ThrowIfNull は paramName を省略してOK(引数名を自動で取れる仕組みがあるよ)🧠✨ (Microsoft Learn)
さらに、こういう分析ルールも「ifでnew例外作るより ThrowIf が良いよ」って推してるよ📏🔍 (Microsoft Learn)
4.2 文字列:null/空/空白を一発で弾く📛🧁
public void ChangeDisplayName(string displayName)
{
ArgumentException.ThrowIfNullOrWhiteSpace(displayName);
// ここから本体
}
ThrowIfNullOrWhiteSpace は null/空/空白だけ をまとめて弾けるよ✨ (Microsoft Learn)
「null か空なら ArgumentException を投げる」みたいなパターンも、専用の推奨ルールがあるよ📌 (Microsoft Learn)
4.3 数値:範囲チェックは ThrowIf 系が超便利📏🚧
public void SetQuantity(int quantity)
{
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(quantity);
// quantity >= 1 が保証された✨
}
ThrowIfNegative/ThrowIfNegativeOrZero/ThrowIfLessThan/ThrowIfGreaterThanなどが使えるよ🧰✨ (Microsoft Learn)
5. “ThrowIf だけで足りない”ときの書き方🧠🛠️
ThrowIf は短くて最高なんだけど、弱点もあるよ👇
- 「エラーメッセージを細かく書きたい」💌
- 「引数同士の関係チェック」🔗
- 「業務エラー(仕様エラー)は例外じゃなく Result で返したい」📩
こういう時は 素直に if + throw でOK😊✨
5.1 引数同士の関係(期間チェック)⏳🔗
public void Reserve(DateOnly start, DateOnly end)
{
// 単体チェック(ここでは例として省略)
if (start > end)
throw new ArgumentException("start must be <= end.");
// ここから本体
}
5.2 メッセージの型(テンプレ)💌🧁
未来の自分が助かるメッセージはこれ👇
- ✅ 何がダメ?(ルール)
- ✅ どの引数?(名前)
- ✅ できれば値も(ログで助かる)
例:
if (maxItems is < 1 or > 1000)
throw new ArgumentOutOfRangeException(nameof(maxItems), maxItems, "maxItems must be between 1 and 1000.");
6. “ガード節が汚くなる”よくある事故と対策😵💫🧯
事故①:if のネスト地獄🌋
// 😵💫読みにくい例
if (customer != null)
{
if (!string.IsNullOrWhiteSpace(customer.Name))
{
// ...
}
}
✅ 対策:上で弾く(ガード節)✨
ArgumentNullException.ThrowIfNull(customer);
ArgumentException.ThrowIfNullOrWhiteSpace(customer.Name);
// ... 本体
事故②:ガード節が散らかる(同じチェックがあちこち)🧹💦
✅ 対策:入口のpublicメソッドに寄せる&テンプレで統一🎀
事故③:例外の種類が毎回バラバラ🎭
✅ 対策:この章の「ミニ辞書📚」に寄せる(チームで固定)🤝✨
7. ガード節テンプレ(コピペ用)🧩🎀
「毎回書くのめんどい!」を減らすための、超よくある形だよ😊
7.1 文字列
ArgumentException.ThrowIfNullOrWhiteSpace(name);
7.2 数値(1以上)
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(count);
7.3 範囲(min〜max)
if (value < min || value > max)
throw new ArgumentOutOfRangeException(nameof(value), value, $"value must be between {min} and {max}.");
7.4 関係(start <= end)
if (start > end)
throw new ArgumentException("start must be <= end.");
8. ミニ演習①:ネスト地獄を“ガード節スタイル”に直す🧪✨
お題(Before)😵💫
public static int CalcTotalPrice(string? couponCode, int quantity, int unitPrice)
{
if (couponCode != null)
{
if (couponCode.Trim().Length > 0)
{
if (quantity > 0)
{
if (unitPrice > 0)
{
// 本体(例)
return quantity * unitPrice;
}
}
}
}
return 0;
}
やること✅
couponCode:null/空白は「クーポンなし扱い」にしてOK(= ガードで弾かない)🙂quantityとunitPrice:1以上じゃないとダメ(= ガードで弾く)🛡️
例(After:ガード節でスッキリ)🌸
public static int CalcTotalPrice(string? couponCode, int quantity, int unitPrice)
{
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(quantity);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(unitPrice);
// couponCode は optional(null/空白ならクーポンなし)
var hasCoupon = !string.IsNullOrWhiteSpace(couponCode);
return quantity * unitPrice;
}
9. ミニ演習②:自分のプロジェクトに“ガード節の型”を入れる🏗️✨
次の3つのメソッドを1つ選んで、ガード節だけ書いてみよう😊📝
CreateUser(string email, string displayName, int age)📧PlaceOrder(Guid customerId, IReadOnlyList<OrderItem> items)🛒Reserve(DateOnly start, DateOnly end, int guests)🗓️
ヒント💡
- 文字列 →
ThrowIfNullOrWhiteSpace - 数値(1以上)→
ThrowIfNegativeOrZero - items →
nullとCount==0を分けるか決める(設計)🧠✨
10. ミニ演習③:AIに“ガード節案”を出させて、人が整える🤖✍️✨
AIは速いけど、最終判断は人間が握るのがコツだよ🤝🌸
そのまま使える依頼文(コピペOK)🧁
- 「このメソッドの Pre条件 を箇条書きで出して」📝
- 「Pre条件を ガード節 にして。例外の型も選んで」🛡️
- 「例外メッセージは 短く・ルールが分かる感じにして」💌
仕上げチェック✅
- 例外の種類が適切?(nullなのに
ArgumentExceptionになってない?)🧐 - ガード節が“入口”に集まってる?🚪
- メッセージが未来の自分に優しい?😊
まとめ:ガード節チェックリスト✅🛡️✨
- 上で弾いて、下の本体をスッキリさせた?🧹
- null / 空 / 範囲 / 関係 の順で並んでる?🪜
- 例外の種類が統一されてる?📚
- ThrowIf を使えるところは使った?(短くなる)💨 (Microsoft Learn)
- “何がダメか”が一瞬で分かる?👀💡