4

I understand what a predicate is and how to create one, but when do I use it? Why would I use it?

for example:

Predicate<string> isUpper = s => s.Equals(s.ToUpper());

Why would I do this or anything like it?

Jesse Liberty
  • 1,314
  • 1
  • 11
  • 26
  • 4
    Predicates (and other lambdas like Action and Func) are useful when you want to pass a funtion to a method and have that method execute it. Many of the linq methods (like Where and Select) utilize them. In your example, if you had a collection of strings and wanted to find uppercase ones, you could do `myCollection.Where(isUpper)` to get only the upper case ones. – Matthew May 18 '21 at 15:05
  • 1
    Does this answer your question? [What is a predicate in c#?](https://stackoverflow.com/questions/1710301/what-is-a-predicate-in-c) or [Delegates: Predicate vs. Action ...](https://stackoverflow.com/questions/566860/delegates-predicate-vs-action-vs-func/567223#567223) – Trevor May 18 '21 at 15:12

4 Answers4

3

Predicates can be stored as variables. This means they can be passed as parameters or stored as member variables in a class. If you're familiar with the strategy pattern this lets you do that but without needing to create a whole class to encapsulate your strategy.

For example, imagine we're using LINQ on an arbitrary list of integers.

We can then do this:

List<int> evenInts = ints.Where(i => i % 2 == 0).ToList();

The predicate allows methods like Where to exist and be used succinctly.

Ben
  • 2,200
  • 20
  • 30
2

Firstly, I'll summarize delegates and lambda expressions.

Delegates


In C#, delegates allow you to create types which represent functions. In other words, delegates allow you to save a reference to a method in a variable. Once, we store a reference to that method, we can use this variable to call the method it is referring to. So you are indirectly calling the method. The term "delegate" in C# very well lives up to the literal meaning of delegate.

To store a reference to a method, you first need to create a compatible delegate:

delegate int MyDelegate(string parameter)

The above statement creates a delegate that can hold a reference to any method that has a return type of int and takes a single string as parameter. For instance, I'm creating a trivial class and a method here for demo:

class AClass 
{
    public int StringLength(string str) { return str.Length; }
}

Once you create a delegate, you can use it like a type:

AClass obj = new AClass()
MyDelegate d = obj.StringLength

Notice I have skipped the parentheses after StringLength. Now I can do this:

int length = d("Hello");

This will indirectly call, obj.StringLength() and the value it returns will be returned by d and stored in length.

There's more to delegates like multicast delegates which are beyond the scope of this answer.

Why are delegates powerful?

They help you to easily pass around functions/methods just like objects. You can pass your own method to a class that knows nothing about your method but will call it later through the delegate. This allows you to embed your custom logic into code that you know nothing about.

Lambda Expressions


A lambda expression is nothing but a function literal. It helps to quickly create a function without creating a new class and a new method. In the previous example, I have created a class called AClass with a method StringLength. You can see that all the method body consists is of a single line. With lambdas, you can skip creating a class and a method and directly specify the method body:

MyDelegate d = str => str.Length;

The Predicate<T> Delegate


Predicate<T> is just another delegate as well, defined as follows:

delegate bool Predicate<T>(T obj)

This is a delegate with a generic parameter. This allows you to pass it a parameter of any type which will be specified later when the delegate variable is created but the return type is always bool. A predicate is, in essence, just a condition, that can be either true or false.

Coming to your question, with predicates, you can pass in such a condition to a method so that the method can use it to check if it holds true for something that is private to that class. You are basically passing in logic that will be executed later.

A common use case of predicates is filtering. If I have a collection of elements, and I want to filter the elements and obtain only those elements for which a condition holds true, I can use a Predicate<T> parameter:


public List<int> Filter(List<int> list, Predicate<int> filter)
{
    public var filteredList = new List<int>();
    foreach (int element in list)
    {
        if (filter(element))
        {
            filteredList.Add(element); //Add to list only if condition holds true for the element
        }
        
    }
}

Now, suppose, I have a list and I want only the even numbers and numbers greater than 5, then I can simply do this:

var numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
var evenNumbers = Filter(numbers, element => element % 2 == 0);    // 2, 4, 6, 8
var numbersGreaterThan5 = Filter(numbers, element => element > 5); // 6, 7, 8, 9

In practice, you will hardly have to create a custom Filter() method since System.Linq already has a method/LINQ operator called Where() that does this for you. The parameter to this Where() method is not a Predicate<T> but an identical(compatibility-wise) Func<T, bool> which is another delegate defined as follows:

delegate TResult Func<in T, out TResult>(T arg)

Func<T, bool> and Predicate<T> are therefore identical regards to the methods they can reference. Moreover, you can create your own delegate with the same signature as the predicate. The framework has a bunch of them defined to make life a bit easier for you.

Amal K
  • 4,359
  • 2
  • 22
  • 44
  • 1
    I knew 90% of that, but it was a brilliant explanation. Thanks for taking the time, I'll stick predicates in my back pocket and use as needed. -jesse – Jesse Liberty Jul 24 '21 at 12:18
1

I have used C# Predicates, they are simply delegates that return booleans. They are useful when you are searching through a collection of objects and want something specific. They are often used to allow you to provide logic at runtime, that can be as simple or as complicated as necessary.

I have used it with third-party control Telerik Treeview to search a particular node.

Kashyap
  • 48
  • 3
0

A Predicate delegate is an in-built generic type delegate. This delegate is defined under System namespace. Predicate delegates are typically used to perform search operations on some data based on a set of criteria. It works with those methods which contain some set of criteria and determine whether the passed parameter fulfill the given criteria or not.

Sample Syntax:

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

Why to use Predicates

some advantages of C# Predicate:

  • The Predicate delegates are useful when we have to filter out a list of values.
  • The predicate delegates can be made inline for one off search function.
  • The predicate delegates can be used when we have to search for items in a generic collection.
  • By using predicate delegates, the length of the code is shortened and either true or false is returned.
  • Anonymous methods, expression of lambda can be assigned to predicate delegates.
  • The predicate delegates provide the logic at runtime and it can be a simple logic or complicated logic