Dev

How to work with Action, Func, and Predicate delegates in C#


While passing objects as arguments is a standard and familiar way to invoke methods, providing methods as arguments to other methods is less so. Nonetheless, we often must pass a method as a parameter to another method when working with event handling in C#. We do this using delegates.

I provided an overview of delegates in an earlier article here. In this article, we’ll examine how we can work with Action, Func, and Predicate delegates in C#. To work with the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

A delegate is a type-safe function pointer that can reference a method that has the same signature as that of the delegate. Delegates are used to define callback methods and implement event handling, and they are declared using the “delegate” keyword. You can declare a delegate that can appear on its own or even nested inside a class.

What are Func, Action, and Predicate delegates? How can they be used?

Func and Action delegates are similar. The basic difference between Func and Action delegates is that the former is used for delegates that return a value, and the latter is used for delegates that don’t return a value.

Func is a delegate that points to a method that accepts one or more arguments and returns a value. Action is a delegate that points to a method that accepts one or more arguments but returns no value. In other words, you should use Action when your delegate points to a method that returns void.

A Predicate is a delegate that accepts one or more generic parameters and returns a Boolean value—you can assume it is something like Func<T,bool>. Predicate delegates are typically used to perform search operations based on a set of criteria.

Using Action delegates in C#

You can take advantage of delegates in C# to implement events and call back methods. A delegate in C# is similar to function pointers of C++, but C# delegates are type safe. You can pass methods as parameters to a delegate to allow the delegate to point to the method.

The following code snippet illustrates the syntax for using Action delegate.

Action<TParameter>

The following code listing shows how you can use Action delegate. This code snippet when executed would print the word “Hello!!!” in the console window.

static void Main(string[] args)
        {
            Action<string> action = new Action<string>(Display);
            action("Hello!!!");
            Console.Read();
        }
static void Display(string message)
        {
            Console.WriteLine(message);
        }

Using Func delegates in C#

Let’s now understand how we can work with Func delegates in C#. Here is the syntax for a Func delegate.

Func<TParameter, TOutput>

The following code snippet illustrates how you can use a Func delegate in C#. It prints the value of Hra (calculated as 40% of basic salary). The basic salary is passed to it as an argument.

static void Main(string[] args)
        {
            Func<int, double> func = new Func<int, double>(CalculateHra);
            Console.WriteLine(func(50000));
            Console.Read();
        }
        static double CalculateHra(int basic)
        {
            return (double)(basic * .4);
        }

Note that the second parameter in the declaration of the Func delegate in the code snippet given earlier represents the return type of the method to which the delegate would point. In this example, the calculated Hra value is returned as double.

Programming Predicate delegates in C#

A Predicate delegate is typically used to search items in a collection or a set of data. Here is the syntax for a Predicate delegate.

Predicate<T>

Note that Predicate<T> is basically equivalent to Func<T,bool>.

Consider the following entity class named Customer.

class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Country { get; set; }
    }

Next, create a list of customers and store objects of type Customer into it.

 List<Customer> custList = new List<Customer>();
            custList.Add(new Customer { Id = 1, FirstName = "Joydip", LastName = "Kanjilal", State = "Telengana", City = "Hyderabad", Address = "Begumpet", Country = "India" });
            custList.Add(new Customer { Id = 2, FirstName = "Steve", LastName = "Jones", State = "OA", City = "New York", Address = "Lake Avenue", Country = "US" });

The following is the complete code listing that shows how we can use a Predicate delegate to search data.

static void Main(string[] args)
        {
            List<Customer> custList = new List<Customer>();
            custList.Add(new Customer { Id = 1, FirstName = "Joydip", LastName = "Kanjilal", State = "Telengana", City = "Hyderabad", Address = "Begumpet", Country = "India" });
            custList.Add(new Customer { Id = 2, FirstName = "Steve", LastName = "Jones", State = "OA", City = "New York", Address = "Lake Avenue", Country = "US" });
            Predicate<Customer> hydCustomers = x => x.Id == 1;
            Customer customer = custList.Find(hydCustomers);
            Console.WriteLine(customer.FirstName);
            Console.Read();
        }

When the above code snippet is executed, the name “Joydip” will be displayed in the console window.

How to do more in C#:

Copyright © 2023 IDG Communications, Inc.



READ SOURCE

This website uses cookies. By continuing to use this site, you accept our use of cookies.