Introduction 
We learned what delegates are in this article.
Whenever we use delegates, we have to declare a delegate, initialize it, and then call a method with a reference variable.
In order to get rid of all the first steps, we can directly use Func, Action, or Predicate delegates.
	- The Func delegate takes zero, one or more input parameters, and returns a value (with its out parameter).
- The action takes zero, one or more input parameters, but does not return anything.
- Predicate is a special kind of Func. It represents a method that contains a set of criteria mostly defined inside an if condition and checks whether the passed parameter meets those criteria or not.
It takes one input parameter and returns a boolean - true or false.
Note. You can use all three of them with anonymous methods and lambda expressions.
Let's first learn the Func delegate.
Syntax 1
One input parameter and one return parameter.
public delegate TResult Func<int T, out TResult>(T arg);  
Syntax 2
Two input parameters and one return parameter.
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg, T2 arg2)
The last parameter in the angle brackets <> is considered as the return type, and the remaining parameters are considered as input parameter types. It can have 0 - 16 input parameters.
Func with 0 parameters
Func<int> SomeMethodName; 
It still has one parameter; it is a return type because func always returns something.
class Program  
   {  
       static void Main(string[] args)  public delegate TResult Func<in T1, in T2, out TResult>(T1 arg, T2 arg2)
       {  
           Func<int,int,int> Addition = AddNumbers;  
           int result = Addition(10, 20);  
           Console.WriteLine($"Addition = {result}");  
       }  
  
       private static int AddNumbers(int param1, int param2 )  
       {  
           return param1 + param2;  
       }          
  } 
Func with an Anonymous Method
Func<int,int,int> Addition = delegate (int param1, int param2)    
{    
    return param1 + param2;    
};    
int result = Addition(10, 20);    
Console.WriteLine($"Addition = {result}");     
Func with Lambda Expression
Func<int, int, int> Addition = (param1, param2) => param1 + param2;  
            int result = Addition(10, 20);  
            Console.WriteLine($"Addition = {result}"); 
Action delegate
Here, the method AddNumbers takes 2 parameters but returns nothing. The results are assigned to an instance variable result.
Even an ion delegate can have 0 - 16 input parameters.
private static int result;  
        static void Main(string[] args)  
        {  
            Action<int, int> Addition = AddNumbers;  
            Addition(10, 20);  
            Console.WriteLine($"Addition = {result}");  
        }  
  
        private static void AddNumbers(int param1, int param2 )  
        {  
            result = param1 + param2;  
        } 
Action with an Anonymous method
private static int result;  
       static void Main(string[] args)  
       {  
           Action<int, int> Addition = delegate (int param1, int param2)  
           {  
               result = param1 + param2;  
           };  
           Addition(10, 20);  
           Console.WriteLine($"Addition = {result}");  
       } 
Action with a Lambda expression
private static int result;  
       static void Main(string[] args)  
       {  
           Action<int, int> Addition  = (param1, param2) => result = param1 + param2; ;  
           Addition(10, 20);  
           Console.WriteLine($"Addition = {result}");  
       } 
Predicate delegate
Syntax difference between predicate & func is that here in predicate, you don't specify a return type because it is always a bool.
.Let's check if the phone is an iPhone or not.
class Program  
{  
    static void Main(string[] args)  
    {  
        Predicate<string> CheckIfApple = IsApple;  
        bool result  = IsApple("I Phone X");  
        if(result)  
        Console.WriteLine("It's an IPhone");  
    }  
  
    private static bool IsApple(string modelName)  
    {  
        if (modelName == "I Phone X")  
            return true;  
        else  
            return false;  
    }  
}  
A predicate with the Anonymous method
Predicate < string > CheckIfApple = delegate(string modelName) {  
    if (modelName == "I Phone X") return true;  
    else return false;  
};  
bool result = CheckIfApple("I Phone X");  
if (result) Console.WriteLine("It's an IPhone");   
A predicate with Lambda expressions
Predicate < string > CheckIfApple = modelName => {  
    if (modelName == "I Phone X") return true;  
    else return false;  
};  
bool result = CheckIfApple("I Phone X");  
if (result) Console.WriteLine("It's an IPhone");   
Wonderful!
That's how you can directly use ready-made delegates without having them declared.
I hope this blog has given you the basic idea of delegate types. Be sure to implement them in your project.