【C#】Predicateとは?Func<T, bool>との違いを初心者向けに解説
以下に、Func<T, bool> と Predicate<T> の違いを解説する初心者向け技術ブログ記事をまとめました。Func<>・Action<> との関連性を踏まえて、Predicate<T> が登場する意義を明確にしています。
C# を学び始めると、Func<> や Action<> に続いて登場するのが Predicate<T>。
この Predicate<T> は、関数型 Func<T, bool> と非常によく似ています。
「結局どっちを使えばいいの?」
「どう違うの?」
そんな疑問に答えます。
1. Predicate は「条件を判定する関数」
Predicate<T> は、「T型の値を受け取り、true / false(bool)で返す関数」を表す型です。
例:
Predicate<int> isEven = x => x % 2 == 0;
Console.WriteLine(isEven(4)); // true
この関数は、「x が偶数なら true、そうでなければ false」を返します。
2. Func<T, bool> との違いは?
結論から言うと:
- 役割は同じ(どちらも「T型を受け取ってboolを返す関数」)
- 型の名前が違うだけ
- Predicate<T> の方が「用途が限定的でわかりやすい」
比較表
比較項目 | Func<T, bool> | Predicate<T> |
---|---|---|
型の意味 | 「T を受け取って bool を返す」 | 同じ |
用途 | 幅広い(汎用的) | 主に「条件判定」や「フィルター」 |
可読性(意図の明確さ) | やや抽象的 | 条件式だとすぐわかる |
汎用性 | 高い | 限定的 |
つまり、意味は同じだけど、目的がはっきりしている方が Predicate。
3. 使われる場面で見る違い
Predicate<T> が使われる標準メソッドの例
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Find:条件に一致する最初の要素を返す(Predicate<int> を受け取る)
int found = numbers.Find(x => x % 2 == 0);
Console.WriteLine(found); // 出力: 2
- Find, FindAll, RemoveAll, Exists, TrueForAll など、List<T> 系のメソッドが Predicate<T> を引数に取る。
一方、Func<T, bool> が使われる場面(LINQ)
var evenNumbers = numbers.Where(x => x % 2 == 0); // Func<int, bool>
- LINQ(Where, Any, All, FirstOrDefault など)は Func<T, bool> を使う。
4. 書き換え可能な例
次のコードは、どちらも同じ意味です。
// Func<int, bool>
Func<int, bool> f1 = x => x > 10;
// Predicate<int>
Predicate<int> f2 = x => x > 10;
このように、意味は完全に一致しています。
5. どっちを使うべき?
- 標準ライブラリ側が要求する方を使う(自分で選べないことも多い)
- 自作のメソッドで「条件を判定する関数」を引数に取りたい場合は Predicate<T> の方が意図が伝わりやすくておすすめ
- より汎用的に使いたい・他の戻り値型にも対応したいなら Func<T, bool>
6. まとめ
- Predicate<T> は Func<T, bool> の特化型
- 「条件を判定する」処理に限定されているので用途が明確
- List系メソッドでは Predicate<T> がよく使われる
- LINQでは Func<T, bool> が使われる
補足:3つの関数型の使い分け早見表
型 | 引数 | 戻り値 | 用途例 |
---|---|---|---|
Action<T> | T | void | メッセージ表示・ログ出力など |
Func<T, R> | T | R | 計算・変換・抽出など |
Predicate<T> | T | bool | 条件判定・フィルタ |
練習問題
Q. 次の Predicate<string> を完成させてください。
「文字列の長さが5以上なら true を返す」
Predicate<string> isLong = ???;
Console.WriteLine(isLong("apple")); // true
Console.WriteLine(isLong("cat")); // false
Predicate<string> isLong = s => s.Length >= 5;
より理解を深めたい方は、「カスタムフィルター処理を作る」「LINQとListの違いを意識して使い分ける」など、実践的な応用にもチャレンジしてみましょう。
ディスカッション
コメント一覧
まだ、コメントがありません