Introduction
So here we are discussing the generic delegates. By using them, we can easily create delegates that do not depend on the data types. We can define their type at run time. Here I have explained in detail and in an easy way how to do them. Before I start with generic delegates, first of all, I want to give a quick introduction to the delegates.
Delegates
Delegates are really very useful features of C# introduced in C# 2.0. They make our projects more secure. We can implement data encapsulation with the help of delegates. Delegates are capable of holding the reference of a method, and then we can access the method without using its actual name with the help of delegates.
Why do we need Generic Delegates?
So why do we really need the Generic Delegates? Let’s have a problematic condition. If there are two methods, or if we have five methods, we can create five delegates. But when we work on such large projects, we may have to create fifty or five hundred delegates. If we want to encapsulate them by using delegates, then we have to create fifty or five hundred delegates. That will really increase the size of our code and make our application slow. Then Generic Delegates is here to help us.
Generic Delegates
By using generic delegates, we don't need to create multiple delegates in order to invoke the method. C# provides three types of delegates to deal with such conditions that may be possible in any method definition. These three types are fully capable of holding the reference of most possible method definitions, which are given below.
- Func Delegate
- Action Delegate
- Predicate Delegate
All three Generic Delegates are found in the System namespace, so we must add the system namespace to our program by using system; this namespace is by default added to the program automatically.
Func Delegate
The func generic delegate is defined in the system namespace. This delegate takes a 1-16 input parameter and must have one return parameter, otherwise it will raise an error like CS7003 There is an unexpected use of an unbound generic name, so it is a must to have a return parameter if you are using Func Generic Delegate. The last parameter is treated as a return type.
Syntax to create Func Delegate
Func<parameter list,output value> Object_name= new Func <parameter list,output value>(method_name);
Let's have an example
suppose we have a method
public static double Addition_Func(int no1, float no2, double no3) {
return no1 + no2 + no3;
}
Here method name is Additon_Func that returns a double value and has three input parameters, to call this method we have to define a delegate like this
Func<int, float, double, double> Func_Object = new Func<int, float, double, double>(Addition_Func);
Here the last parameter is double, which is the return type of the passed method Addition_Func. When we call the method with the object this will invoke the Addition_Func.
Invoking the method by using Func Generic delegate.
There are two ways available in C# to invoke method
- Object_Name(parameters);
- Object_Name.Invoke(parameters);
Let's have a quick introduction to Invoke Keyword
Invoke
This will invoke the specified method that is assigned to the Delegate object. This will search for the method in their parent class until it is not found. This will schedule the method to the thread once it receives the method definition.
Note
it is not mandatory to use Invoke to invoke the method.
Invoking without Invoke
double Result = Func_Object(100, 125.45f, 456.789);
Here we call the method Addition_Func that is previously passed to Func_object. Here we created a double type variable Result that holds the return value that is produced by Addition_Func.
Invoking with Invoke
double Result = Func_Object.Invoke(100, 125.45f, 456.789);
Here almost things are the same except Invoke keyword
Both invocations produce the same output after the execution
Action Delegate
The Action Delegate is needed when we need to invoke a method that doesn't have any return type. Action Delegate is capable of taking a maximum of 16 parameters as arguments, which means it has 16 overload methods.
Syntax to create Action Delegate
Action<parameter list,output value> Object_name= new Action <parameter list,output value>(method_name);
Let's have an example
suppose we have a method
public static void Addition_Action(int no1, float no2, double no3) {
Console.WriteLine(no1 + no2 + no3);
}
Here method name is Addition_Action which does not return any type of value but has three input parameters to call this method, we have to define a delegate like this
Action<int, float, double> Action_Object = new Action<int, float, double>(Addition_Action);
Here we created an object of Action class that is Action_object. Here we passed the same parameters as presented in the Addition_Action method definition
to invoke this method we use
Action_Object.Invoke(50, 255.45f, 123.456);
object name .invoke and passing the required parameters
Predicate Generic Delegate
The Predicate Generic Delegate is useful in such conditions where we need to pass a String to a method. In Predicate Generic Delegate there is only one argument that can be passed. By default Predicate Generic Delegate returns a Boolean value that may be true or false
Syntax to create Predicate Generic Delegate
Predicate<String> Object_name= new Predicate<String>(method_name);
Let's have an example
suppose we have a method
public static bool Validate_string(string name) {
if (name.Length < 15) return true;
return false;
}
Here method name is Validate_string that returns a boolean value and has one input parameter of string type to call this method we have to define a Predicate delegate like this
Predicate<string> Predicate_Object = new Predicate<string>(Validate_string);
to invoke this method we use
bool Status = Predicate_Object.Invoke("shivam payasi");
Here we created a bool type variable Status that holds the value returned by method Validate_string
Let's have a look at all examples
using System;
namespace Generic_DeleGates {
public class GenericDelegates {
static void Main(string[] args) {
Func < int, float, double, double > Func_Object = new Func < int, float, double, double > (Addition_Func);
double Result = Func_Object.Invoke(100, 125.45 f, 456.789);
Console.WriteLine("Result of Addition with Func Generic Delegate: " + Result);
Action < int, float, double > Action_Object = new Action < int, float, double > (Addition_Action);
Action_Object.Invoke(50, 255.45 f, 123.456);
Predicate < string > Predicate_Object = new Predicate < string > (Validate_string);
bool Status = Predicate_Object.Invoke("shivam payasi");
Console.WriteLine("Resultwith Predicate Generic Delegate: " + Status);
Console.ReadLine();
}
public static double Addition_Func(int no1, float no2, double no3) {
return no1 + no2 + no3;
}
public static void Addition_Action(int no1, float no2, double no3) {
Console.WriteLine("Result of Addition with Action Generic Delegate: " + (no1 + no2 + no3));
}
public static bool Validate_string(string name) {
if (name.Length < 15) return true;
return false;
}
}
}
Here is the output
Summary
Here we started with a quick introduction of Delegates and then discussed Generic Delegates and their types.
All three types of generic delegate are useful in their appropriate conditions. One thing to remember is that the Func Generic Delegate is very useful when we need to call functions that have one return value and multiple input values or no input parameters. Action Generic Delegate is useful when we need to call a function that doesn't have any return value but has a single or multiple input values. The Predicate Generic Delegate is useful when we need to call a function that returns a boolean value and has a string parameter as input.