【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>Tvoidメッセージ表示・ログ出力など
Func<T, R>TR計算・変換・抽出など
Predicate<T>Tbool条件判定・フィルタ

練習問題

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の違いを意識して使い分ける」など、実践的な応用にもチャレンジしてみましょう。

訪問数 4 回, 今日の訪問数 1回