Action, Func and Predicate are pre-defined Generic delegates. So as delegate they can point to functions with specified signature.
Action<>
Does not return any value, and can take from none up to 16 generic parameters. So there are total of 17 overloads for Action delegate, from no parameter to up to 16 generic parameters. As it does not return any value, so conventionally named as Action.
- Action
- Action<T>
- Action<T1, T2>
- Action<T1, T2, T3>
- Action< ……
static void Shout(string arg1, string arg2)
{
Console.WriteLine(string.Format("{0} {1}!", arg1, arg2));
}
static void Main(string[] args)
{
//Create an Action
Action<string, string> action = new Action<string,string>( Shout );
//OR You can initialize it as
Action<string, string> moreAction = Shout;
//Invoke method.
moreAction("Hello", "World");
//will output 'Hello World!'
}
Actual delegate definition of Action<T1, T2> would be:
public delegate void Action<T1, T2>(T1 param1, T2 param2);
Func<>
Return a generic parameter, and has 17 overloads to support from none up to 16 generic parameters. Last parameter is the Return type, and is required. As it does return a parameter, so conventionally named as Func derived from Function.
- Func<TResult>
- Func<T1, TResult>
- Func<T1, T2, TResult>
- Func<T1, T2, T3, TResult>
- Func< ……
Actual delegate definition of Func<T1, T2, out TResult> with two parameters would be:
public delegate TResult Func<T1, T2, out TResult>(T1 param1, T2 param2);
Predicate<>
As name indicate, this delegate defines a method with return type bool, and exactly one generic parameter. Method is pretty much used as a function to affirm or deny certain input for specific operation. i.e Either provided input is true or false based on specific method implementation. Mostly used as a filter method for given data.
For example, FindAll method for List<T> takes Predicate<T> method as parameter. FindAll method use provided method against Predicate<T> to apply and filter against each value of the collection based on Predicate response.
static bool IsEvenNumber(int num)
{
return num % 2 == 0;
}
static void Main(string[] args)
{
//Predicate
Predicate<int> isEvenPredicate = IsEvenNumber;
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> evenNumbers = numbers.FindAll(isEvenPredicate);
// output will be 2,4,6,8
}
Actual delegate definition for Predicate would be:
public delegate bool Predicate<T>(T input);
What are the advantages of pre-defined delegates?
- To save time from defining a delegates of similar definition yourself. Use the predefined one which is also more commonly used, and well recognized.
- With the invent of Extension methods and LINQ which introduced loads of functions with the requirement of delegate parameter. A presence for general globally defined pre-defined delegates was required.
Hope that clarify the concept.