In C#, we can also pass a method as a parameter to a different method using a delegate. We use the delegate
keyword to define a delegate.
Modifer delegate returnType Name(parameter)
Here, Name is the name of the delegate and it is taking parameter. Suppose we have a delegate having int
as the parameter.
public delegate void Name(int x)
In this case, our delegate will take a method (name of a method) which will also have an int
as its parameter and void
return type. It means the method passed to a delegate must have the same parameters and return type.
Let's take a look at the following code snippet.
using System;
class Test
{
public delegate int NewDelegate(int x, int y);
static int Add(int x, int y)
{
return x+y;
}
}
Here, NewDelegate is a delegate which has two integers parameter x and y. It means that it will take a method which also has two integers as its parameter and also integer return type. So, it can take the method Add.
To create a new delegate, we either use the new
keyword or simply decalare as we declare variables.
using System;
class Test
{
public delegate int NewDelegate(int x, int y);
static int Add(int x, int y)
{
return x+y;
}
static int Subtract(int x, int y)
{
return x-y;
}
static void Main(string[] args)
{
NewDelegate d1 = Add;
NewDelegate d2 = Subtract;
}
}
In this example, we have declared two delegates d1 and d2 and assigned Add and Subtract respectively.
Let's use the new
keyword to make delegates.
using System;
class Test
{
public delegate int NewDelegate(int x, int y);
static int Add(int x, int y)
{
return x+y;
}
static int Subtract(int x, int y)
{
return x-y;
}
static void Main(string[] args)
{
NewDelegate d1 = new NewDelegate(Add);
NewDelegate d2 = new NewDelegate(Subtract);
}
}
In this example, we have used the new
keyword to make delegates. Let's use these delegate to invoke the respective methods. So, invoking d1 will invoke Add method and invoking d2 will invoke the Subtract method.
using System;
class Test
{
public delegate int NewDelegate(int x, int y);
static int Add(int x, int y)
{
return x+y;
}
static int Subtract(int x, int y)
{
return x-y;
}
static void Main(string[] args)
{
NewDelegate d1 = new NewDelegate(Add);
NewDelegate d2 = new NewDelegate(Subtract);
Console.WriteLine(d1(10, 20));
Console.WriteLine(d2(10, 20));
}
}
As you can see by using d1(10, 20)
, we used Add method and by using d2(10, 20)
, we used Subtract method.
C# Invoke
We can also use the Invoke
method to invoke a delegate.
using System;
class Test
{
public delegate int NewDelegate(int x, int y);
static int Add(int x, int y)
{
return x+y;
}
static int Subtract(int x, int y)
{
return x-y;
}
static void Main(string[] args)
{
NewDelegate d1 = new NewDelegate(Add);
NewDelegate d2 = new NewDelegate(Subtract);
Console.WriteLine(d1.Invoke(10, 20));
Console.WriteLine(d2.Invoke(10, 20));
}
}
Passing Delegate To Method in C#
We can also pass a delegate to a method. Let's look at the example given below.
using System;
class Test
{
public delegate int NewDelegate(int x, int y);
static void Display(NewDelegate d)
{
Console.WriteLine(d(10, 20));
}
static int Add(int x, int y)
{
return x+y;
}
static void Main(string[] args)
{
NewDelegate d1 = new NewDelegate(Add);
Display(d1);
}
}
In this example, the Display method is taking a delegate NewDelegate as its parameter and then invoking it in Console.WriteLine(d(10, 20));
.
C# Multicast Delegate
In C#, a delegate can also point to multiple methods and is known as multicast delegate. We use +
and -
operators to add and subtract methods from a delegate.
So, if d is a delegate, then we can add a method M to it using d = d+M
or d += M
. In this case, invoking d will invoke all the methods in d sequentially.
Similarly, we can use -
to remove methods from a delegate. Let's take an example.
using System;
class Test
{
public delegate void NewDelegate();
static void Display1()
{
Console.WriteLine("Hello");
}
static void Display2()
{
Console.WriteLine("CodesDope");
}
static void Main(string[] args)
{
NewDelegate d = Display1;
d = d+Display2;
d();
d = d-Display2;
d();
}
}
C# Func
C# also provides a built-in generic delegate in System namespace Func
. We can use Func
if we don't want to create our own delegate. Let's look at its syntax.
Func<type1, type2, type3, type4> name;
Here, name is just the name of the func delegate. type1, type2 and type3 are the type of input parameters and type4 is return type. It means our func delegate name will point to a function which takes three parameters of type - type1, type2 and type3 and has a return type of type4.
Func can take 0 to 16 input parameters. For example if a func has no input parameter and only has a return type of int
, it will be decalred as:
Func<int> name;
If a function has an integer and a double parameter and has an integer return type, it will be declared as:
Func<int, double, int> name;
Take a note that a func can't have a void return type. So, a func must return something.
Let's take an example.
using System;
class Test
{
static int Add(int x, int y)
{
return x+y;
}
static void Main(string[] args)
{
Func<int, int, int> f = Add; //first two int are parameter type. Last int is return type
int x = f(10, 20);
Console.WriteLine(x);
}
}
Func<int, int, int>
→ Here, the first two int
are parameter type and the last int
is the return type. Thus, we pointed to a function with two integer parameters and integer return type also - int Add(int x, int y)
.
C# Action
Action is also a predefined delegate in the System namespace and is used when we don't want to create our own delegate.
It is exactly the same as Func
but it doesn't return anything. So, it is used to point a function having void return type.
using System;
class Test
{
static void Display(int x)
{
Console.WriteLine(x);
}
static void Main(string[] args)
{
Action<int> f = Display;
f(10);
}
}
C# Predicate
A Predicate is also a delegate which returns a boolean. It is generally used to check specific conditions. For example, a method to check if a number is positive or not will return a boolean because the result will be either true or false. We can use predicate if we want a delegate for this function.
It is also declared similar to Action
and since it must return a boolean, we don't write the return type with the parameter.
A predicate can take only one input parameter.
using System;
class Test
{
static bool IsPositive(int x)
{
if(x>0)
return true;
return false;
}
static void Main(string[] args)
{
Predicate<int> p = IsPositive;
Console.WriteLine(p(10));
Console.WriteLine(p(-10));
}
}