In the previous article, we learned about the delegates and their types. Now in this article, we are going to discuss the ‘generic delegates in C#‘.
Table of Contents
What are the generic delegates in C#?
The Func, Action, and Predicate are the three generic delegates that were introduced in .NET 3.5
and are available in the System
namespace.
They are like ready-made templates for functions that you can use in your code. Here’s why and how you should use them:
Func
The Func delegate represents a method that can take input parameters from 0 to 16 and return a single value. You should use it when you want to define a method that always returns a value, like a mathematical calculation.
For example:
using System;
public class GenericDelegateExample
{
public static void Main(string[] args)
{
Func<int, int, int> add = (a, b) => a + b;
int result = add(5, 3);
Console.WriteLine($"Output : {result}"); // Result will be 8
}
}
Action
The Action delegate is similar to Func, but it doesn’t return a value (void). It can also take from 0 to 16 input parameters. This delegate is used for methods that perform an action but don’t return a result, like logging or printing to the console.
For example:
using System;
public class GenericDelegateExample
{
public static void Main(string[] args)
{ // Action Delegate Example
Action<string> greet = (name) => Console.WriteLine($"Hello, {name}!");
greet("Radha"); // Prints "Hello, Radha!"
}
}
Predicate
The Predicate delegate represents a method that takes a single parameter and returns a Boolean value. So, If you need a delegate to check a condition and return a Boolean result, go for Predicate.
It takes only one input parameter and returns true or false.
Predicate delegate is great for scenarios where you need to check conditions, like filtering a list based on a specific criterion.
For Example:
// Example: 1
Predicate<int> isEven = (num) => num % 2 == 0;
bool even = isEven(6); // 'even' will be 'true'
// Example: 2
Predicate<string> isLong = s => s.Length > 5;
bool result = isLong("example"); // result is true
We can make use of all these three predefined generic delegates when we want to invoke the methods without defining the delegates explicitly.
Let’s understand these generic delegates in more details.
Func delegate in C#
The Func is a generic delegate that is available in the System namespace.
It can take up to 16 input parameters of the same or different data types and one out parameter.
- The last parameter in the ‘Func delegate‘ is always considered an out parameter to return the value.
- The input parameters are optional, but the out parameter is mandatory to pass in the Func delegate.
- Func delegate can also be used with the anonymous method and the lambda expression.
We can use Func delegate to point those methods which can take zero, one or more input parameters, and return some value.
Note: Func delegate doesn’t allow passing ref and out parameters.
Syntax of Func delegate
// Signature to define Func delegate.
public delegate TResult Func<in T, out TResult>(T arg);
// Func delegate can take up to 16 input parameters and one out parameter.
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
//The last parameter is an out parameter
Example to define a delegate in C#
Before moving forward, let’s first create an example of a simple single cast delegate, and later on, we will achieve the same thing using the Func delegate.
To create a normal delegate we have to follow these four steps.
- Declare a delegate type
- Create methods having the same signature as the delegate type
- Create an instance of the delegate type
- Invoke the delegate object
In the following example, we are defining a delegate separately.
using System;
namespace DelegateDemo
{
class Program
{
// Declaring a delegate
public delegate double MyDelegate(int num1, float num2);
static void Main(string[] args)
{
// Instantiating the delegate
// and passing the method as parameter
MyDelegate myDelegate = new MyDelegate(AddNumbers);
// Invoking a delegate
double output = myDelegate.Invoke(10, 20.5f);
Console.WriteLine($"Output : {output}");
}
// Create method having same signature as delegate
public static double AddNumbers(int num1, float num2)
{
return num1 + num2;
}
}
// Output : 30.5
}
In the above program, we have defined a delegate explicitly to point to a method called “AddNumbers”.
This method takes two input parameters of int and float type and returns a double value.
Once we run the program we will get the result as expected.
Defining the delegate like above is fine, except when we need to define so many delegates explicitly to point to multiple methods having different signatures.
So defining like the above delegate to point matching method signature can be eliminated by using the generic delegates in C#.
To eliminates defining the delegate separately we can use the generic delegates. Let’s create the above program using a Func generic delegate.
Example of Func delegate
using System;
namespace FuncDelegateDemo
{
class Program
{
static void Main(string[] args)
{
Func<int, float, double> funcDelegate = AddNumbers;
double output = funcDelegate.Invoke(10, 20.5f);
Console.WriteLine($"Output : {output}");
}
public static double AddNumbers(int num1, float num2)
{
return num1 + num2;
}
}
// Output : 30.5
}
The following is the output of the above program.
Example of Func delegate with an anonymous method
In the following example, we are assigning an anonymous method to the Func delegate by using the delegate keyword.
If we are using an anonymous method, we don’t need to declare a separate named method.
You can read more about the anonymous method here.
using System;
namespace FuncDelegateDemo
{
class Program
{
static void Main(string[] args)
{
Func<int, float, double> funcDelegate = delegate (int num1, float num2)
{
return num1 + num2;
};
double output = funcDelegate.Invoke(10, 20.5f);
Console.WriteLine($"Output : {output}");
}
}
// Output : 30.5
}
In the above example, an anonymous method is directly assigned to the Func delegate which takes two input parameters. An anonymous method is useful when we want to write an inline statement without creating a separate named method.
Example of Func delegate with the lambda expression
In the following example, we are using Func delegate with the lambda expression. Lambda expression is basically shorthand or an enhancement for declaring an anonymous method in C#.
using System;
namespace FuncDelegateDemo
{
class Program
{
static void Main(string[] args)
{
Func<int, float, double> funcDelegate = (int num1, float num2) => (num1 + num2);
double output = funcDelegate.Invoke(10, 20.5f);
Console.WriteLine($"Output : {output}");
}
}
// Output : 30.5
}
Action delegate in C#
The Action delegate is very similar to the Func delegate. It can also accept up to 16 input parameters but it doesn’t return any value.
‘Action delegate‘ is a generic delegate in which the return type is always void. We can use action delegate to point to those methods which return void and accept zero or more input parameters.
Action delegates are of two types:
Action: Encapsulates a method that has no parameters and does not return a value.
Action<in T1,…,inT16>: Encapsulates a method that has zero or more input parameters of the same or different data types and does not return a value.
Syntax of Action delegate
// Encapsulates a method that has a single parameter and does not return a value.
public delegate void Action<in T>(T obj);
// Encapsulates a method that can accept up to 16 input parameter and
// does not return a value.
public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
// The Action generic delegate can accept zero to 16 input parameters.
Example of non-generic Action delegate
The non-generic delegate takes the reference of a method that returns void and has no parameter.
using System;
namespace ActionDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Non generic action delegate
Action action = PrintName;
action.Invoke();
}
public static void PrintName()
{
Console.WriteLine("Shekh Ali");
}
}
// Output : Shekh Ali
}
Example of Action generic delegate
In the below example, we are using Action delegate to hold the reference of a method that is accepting two input parameters of integer type and returns void.
using System;
namespace ActionDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Generic Action delegate
Action<int,int> action = AddTwoNumbers;
action.Invoke(30,20);
}
public static void AddTwoNumbers(int num1, int num2)
{
Console.WriteLine(num1 + num2);
}
}
// Output : 50
}
Action generic delegate with an anonymous method
using System;
namespace ActionDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Generic Action delegate with anonymous method
Action<int, int> action = delegate (int num1, int num2)
{
Console.WriteLine(num1 + num2);
};
action.Invoke(30, 20);
}
}
// Output : 50
}
Action generic delegate with the lambda expression
In the below example we are using Action delegate with the lambda expression.
using System;
namespace ActionDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Generic Action delegate with lambda expression
Action<int, int> action = (num1, num2) =>
{
Console.WriteLine(num1 + num2);
};
action.Invoke(30, 20);
}
}
// Output : 50
}
Predicate generic delegate in C#
The Predicate is a generic delegate which is available in System namespace.
It takes one input parameter and returns a boolean value.
A predicate delegate is generally used to check whether a parameter meets a specific condition or not.
If it meets the criteria it will return true otherwise false .
The Predicate delegate is mostly used in a lambda expression to filter the results.
Syntax of predicate delegate
Following is the syntax to declare generic predicate delegate in C#.
public delegate bool Predicate<in T>(T obj);
Example of Predicate delegate
In the following example, we are checking whether the entered number is even or not. If the entered number is even it will return true otherwise false.
using System;
namespace PredicateDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Predicate delegate
Predicate<int> predicate = IsEvenNumber;
bool result = predicate.Invoke(10);
Console.WriteLine(result);
}
public static bool IsEvenNumber(int number)
{
if (number % 2 == 0)
return true;
else
return false;
}
}
// Output : True
}
Predicate delegate with an anonymous method
using System;
namespace PredicateDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Predicate delegate with anonymous method
Predicate<int> predicate = delegate(int number)
{
if (number % 2 == 0)
return true;
else
return false;
};
bool result = predicate.Invoke(10);
Console.WriteLine(result);
}
}
// Output : True
}
Predicate delegate with the lambda Expression
using System;
namespace PredicateDelegateDemo
{
class Program
{
static void Main(string[] args)
{
// Predicate delegate with lambda expression
Predicate<int> predicate = (number)=>
{
if (number % 2 == 0)
return true;
else
return false;
};
bool result = predicate.Invoke(10);
Console.WriteLine(result);
}
}
// Output : True
}
Conclusion:
Today we learned all about the generic delegates available in C# such as Func, Action, and Predicate delegates with multiple examples.
FAQs:
Q: Delegate in C#: What does it mean?
A delegate is a reference type data type that refers to any method with the same signature as the delegate.
Delegates are commonly used for event handling, callback mechanisms, and dynamic method invocation. They provide flexibility and decouple the caller from the actual method implementation.
Q: What are the different types of delegates in C#?
There are three types of delegates available in C#:
1. Single Delegate
2. Multicast Delegate
3. Generic Delegate (Func, Action, and Predicate delegate)
Q: Why is delegate used in C#?
In C#, Delegates are mainly used to define callback methods and implement event handling and are declared using the “delegate” keyword.
Q: What is the difference between event and delegate in C#?
A delegate is a function pointer. It holds the reference of one or more methods with the same signature at runtime. The delegate is independent and doesn’t rely on events. On the other hand, An event is dependent on a delegate and cannot be created without delegates.
Q: Why should I use generic delegates?
Using generic delegates simplifies code by providing a standardized way to work with methods.
Instead of defining custom delegate types for each method signature, you can use Action
delegate for methods that don’t return a value, Func
delegate for methods that return a value, and Predicate
delegate for methods that return a Boolean value.
Recommended Articles:
- Understanding C# Delegates (with Examples)
- 10 Difference between interface and abstract class In C#
- C# 10 New features with examples | What’s new in C# 10?
- C# Array vs List
- Serialization and Deserialization in C#
- C# Monitor class in multithreading with examples
- Exception Handling in C#| Use of try, catch, and finally block
- C# Enum | How To Play With Enum in C#?
- C# extension methods with examples
- Properties In C# with examples
- IEnumerable Interface in C# with examples
- Constructors in C# with Examples
I truly hope you enjoyed and learned from this article “Generic Delegates in C#”. Please leave any feedback, comments, or questions in the comment section below.
- Difference Between Array And ArrayList In C#: Choosing the Right Collection - May 28, 2024
- C# Program to Capitalize the First Character of Each Word in a String - February 21, 2024
- C# Program to Find the Longest Word in a String - February 19, 2024