Introduction
  In this article, we are going to discuss Action and Func delegates in C# and
  how we use them. As we already know, a Delegate in C# is a type-safe method
  pointer and we are using it to handle the callback or an event. Actions and
  Funcs are just delegates but are pre-defined in System Namespace so that we
  don’t need to define the custom delegates manually.
Syntax
  Both Action and Func delegates can have multiple input parameters. A Func
  delegate returns a value while an Action does not, this is the only difference
  between them.
  C# provides 17 overloads of Action delegate in the System Namespace, one of
  them is:
public delegate void Action<in T>(T obj);
This Action delegate would only accept one argument of type T. However,
      it can support up to 16 arguments of type T.
  
  Similarly, there are total of 17 overloads of Func delegate defined in
      the System Namespace, one of them is:
public delegate TResult Func<out TResult>();
This Func delegate doesn't take any input but returns the result of the type
  TResult. However, it can support up to 16 arguments of type T.
Code Examples
  
    Let’s write a small C# console program so that we understand how to use the
    Action and Func delegates and what are various ways or expressions to assign
    a method reference to those.
  
  
  Let’s start with Action delegate first:
 
static void PrintAWord(string name) 
{ 
  Console.WriteLine(name); 
} 
static void Main(string[] args) 
{
   List<string> words = new List<string> { "apple", "banana", "cherry", "date" }; 
   
   Action<string> actionPrintWord = PrintAWord; 
   
   words.ForEach(w=> actionPrintWord(w)); 
}
  
    In this example, we are going to print all the string fromList collection so
    let's create a list of strings first and then an Action<string>
    delegate that accepts the one string parameter. Now let's use the
    List<String>.ForEach method with an Action<string> delegate as
    an argument to print out each string in the list.
  
  
  We can shorten this example by using the anonymous method:
 
static void Main(string[] args)
{ 
  List<string> words = new List<string> { "apple", "banana", "cherry", "date" }; 
  words.ForEach(delegate(string word){ 
    Console.WriteLine(word); 
  }); 
}
  Furthermore, we can make this example more readable by using the lambda
  expression which we also call the arrow expression:
static void Main(string[] args)
{
    List<string> words = new List<string> { "apple", "banana", "cherry", "date" }; 
    words.ForEach(w=> Console.WriteLine(w));
}
  
    With this, we conclude the various ways to create the Action delegate.
  
  
  Now let’s see the Func delegate example:
 
  static int Square(int n)
{
     return n * n;
}
  
static void Main(string[] args)
{
     Func<int, int> funcSquare = Square;
     Console.WriteLine(funcSquare(5));
}
  
    In this example, we define a Func<int, int> delegate - funcSquare that
    refers to the method int square(int) which represents a mathematical
    function that squares a number. Now let's print the square of 5 in the
    console by calling the funcSquare(5) in the Console.WriteLine() method.
  
  
  We can shorten this example by using the anonymous method:
 
static void Main(string[] args) 
{ 
   Func<int, int> funcSquare = delegate(int n) { return n * n; }; 
   Console.WriteLine(funcSquare(5)); 
}
  Furthermore, we can make this example more readable by using the lambda/arrow
  expression:
static void Main(string[] args) 
{ 
    Func<int, int> funcSquare = n => n * n; 
    Console.WriteLine(funcSquare(5)); 
}
  
    With this, we conclude the various ways to create the Func delegate.
  Conclusion
  
    In this article, we have learned that Action and Func delegates are easy and
    quick to define delegates, thus helping us to keep the code shorter and more
    manageable. We should use generic Action<T> delegate to refer to a
    method that has zero or more parameters and returns void, and use generic
    Func<T,TResult> delegate to refer to a method that has zero or more
    parameters and returns a value.
  
 
  
 
Comments