How to Use the Predicate Delegate in C

The Predicate<T> delegate in C# is a built-in generic delegate used to determine whether a given object meets a specific set of criteria. This article covers the fundamental definition of Predicate<T>, explores its most common use cases—particularly within collection methods like List<T>.FindAll and List<T>.RemoveAll—and explains how it relates to modern lambda expressions and the standard Func<T, bool> delegate.

What is the Predicate Delegate?

Defined in the System namespace, the Predicate<T> delegate represents a method that accepts a single object of type T and returns a boolean value (true or false).

Its formal signature is:

public delegate bool Predicate<in T>(T obj);

If the object satisfies the conditions specified within the delegate method, it returns true; otherwise, it returns false.

Common Use Cases in C

The Predicate<T> delegate is most commonly used in conjunction with generic collection classes, such as List<T> and Array, to perform search, filtering, and removal operations without requiring manual iteration through loops.

Key methods on List<T> that take a Predicate<T> include:

  • Find(Predicate<T>): Returns the first element that matches the conditions defined by the predicate.
  • FindAll(Predicate<T>): Retrieves all elements that match the conditions.
  • Exists(Predicate<T>): Determines whether the collection contains elements that match the criteria.
  • TrueForAll(Predicate<T>): Determines whether every element in the collection matches the criteria.
  • RemoveAll(Predicate<T>): Removes all elements that match the conditions defined by the specified predicate.

Code Example

In modern C#, you typically supply a Predicate<T> using an inline lambda expression rather than declaring an explicit delegate variable or named method.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 12, 8, 21, 44, 3, 18 };

        // Define a predicate to find numbers greater than 10
        Predicate<int> isGreaterThanTen = n => n > 10;

        // Use Find with the predicate variable
        int firstMatch = numbers.Find(isGreaterThanTen);
        Console.WriteLine($"First number > 10: {firstMatch}"); // Output: 12

        // Use FindAll with an inline lambda expression
        List<int> allMatches = numbers.FindAll(n => n > 10);
        Console.WriteLine($"All numbers > 10: {string.Join(", ", allMatches)}"); // Output: 12, 21, 44, 18

        // Remove elements using a predicate
        numbers.RemoveAll(n => n % 2 != 0); // Removes all odd numbers
        Console.WriteLine($"Remaining even numbers: {string.Join(", ", numbers)}"); // Output: 12, 8, 44, 18
    }
}

Predicate<T> vs. Func<T, bool>

A Predicate<T> and a Func<T, bool> are functionally identical; both represent a function that takes an argument of type T and returns a boolean.

The distinction exists primarily for historical reasons:

  • Predicate<T> was introduced in .NET Framework 2.0 to support generic collections.
  • Func<T, bool> was introduced in .NET Framework 3.5 alongside LINQ to provide a standardized set of delegates.

While LINQ extension methods (such as Where and Any) use Func<T, bool>, methods native to List<T> (such as Find and RemoveAll) continue to expect Predicate<T>. When using lambda expressions, the C# compiler automatically infers the target delegate type, allowing the same lambda syntax to work seamlessly in both scenarios.