This C# developer tutorial will discuss the topic of delegates, generic delegates, and anonymous functions. We will explore these concepts alongside code examples showing how to use them.
What is a Delegate in C#?
A delegate is a reference type variable that holds the reference to methods having the same signature and return type. Delegates in C# work the same way as function pointers in C/C++. By using delegates, you can pass a method as a parameter. You can also handle callback functions and event handlers in C# by using delegates.
There are a few steps involved in working with delegates:
- Declaring a delegate
- Instantiating a Delegate
- Calling a delegate
How to Declare a Delegate in C#
You can declare a delegate using the delegate keyword, followed by the function signature. The syntax of a C# delegate is as follows:
[modifier] delegate [return type] [delegate name]([parameters])
Example:
public delegate double ExampleDelegate(int a, int b, int c);
A delegate calls the methods that are compatible with its signature and return type. It does not matter whether a method is an instance method or a static method. Note, an instance method is one that is associated with an instance and a static method is one that is associated with a class name.
Read: Best IDEs for .NET Developers
How to Instantiate a Delegate in C#
Once you declare a delegate, then you can instantiate that delegate with the help of the new keyword.
Note that, for static methods, a delegate object encapsulates the name of the method. However, for non-static methods, a delegate encapsulates both – the object and the method on that object. Here are some examples:
DelegateType delegateTypevariable=new DelegateType(object.methodName)//for Non-static method DelegateType delegateTypevariable=new DelegateType(methodName)//for static method
Read: Code Refactoring Tips for C#
How to Call or Invoke a Delegate
You can invoke a delegate object by using the name of the delegate object, followed by the arguments list to be passed to the delegate. You can call a delegate in C# using the following syntax:
delegate(parameter1,parameter2);
Let’s now briefly see how to declare, instantiate, and invoke delegates using the following code snippet:
class Main{ Delegate double AreaDelegateFunc(int r); //declaring a delegate static Double AreaOfCircleFunc(int radius){ return 3.14*radius*radius } static Double AreaOfSquareFunc(int side){ return side*side } public static void main(){ Static AreaDelegateFunc areaOfCircle= AreaOfCircleFunc; //instantiating delegate Static AreaDelegateFunc areaOfSquare= AreaOfSquareFunc; //instantiating delegate calculateArea(areaOfCircle) // Calling a Delegate } } public static void calculateArea(AreaDelegateFunc delegateGetArea){ delegateGetArea(3); }
In the next section, we will talk about the anonymous method version of delegates and how lambda expressions make the syntax more concise.
Read: Visual Studio Tools to Help You Code Faster
What Are Anonymous Methods in C#?
Anonymous methods in C# are defined with the keyword delegate, which you can assign to a variable of the delegate type. Using this function reduces the coding overhead from instantiation because you do not need to create each method separately. Anonymous methods were introduced in C# 2.0 and are defined without any name.
With the anonymous method, you can access outer functions as well as variables. Anonymous functions can also be passed as a parameter and can also work as an event handler.
Below is an example that shows the functioning of the delegate method in C#:
class Example{ delegate double AreaOfSquareDelegate(int side); Public static void main() { AreaOfSquareDelegate areaOfSquare= delegate(int side){ return side*side; }; Double area= areaOfSquare(4); } }
Lambda Expressions and Anonymous Methods in C#
In C#, the syntax of the anonymous method is reduced with the lambda expression – or, another way you can look at it is to say it is a shorter way of representing anonymous methods. Lambda expression uses the lambda declaration operator (=>) to separate the parameter list from the expression. For creating a lambda expression, you place input parameters on the left side of the lambda operator and you specify the statement block on the right side.
Below is some sample code showing how to use a lambda expression to make the code shorter in C#.
Here is the anonymous method version of delegate:
namespace MyApplication { delegate void ArithmeticOperation(double operand1, double operand2); class Example { static void Main(string[] args) { ArithmeticOperation multiply = (double number1, double number2) => { Console.WriteLine($"{number1} * {number2} = {number1 * number2}"); }; multiply(10, 7); Console.WriteLine(); } } }
Here is the concise version of the above code (using lambda expression):
ArithmeticOperation multiply = (number1, number2) => Console.WriteLine($"{number1} * {number2} = {number1 * number2}");
Here, using lambda expression, the code can be reduced to a fewer number of lines by excluding the parameter types and omitting the curly braces for a single line of statement.
In the next section, we will briefly look at generic delegates then we will talk about how lambda expressions can be assigned to the Func delegate.
Read: Delegates and VB.Net
Generic Delegate Types in C#
C# introduced generic delegate types such as Func and Action. Generic delegates are present in the System namespace. Generic delegates allow programmers to not have to create a custom delegate for each type. Below is the syntax of a generic delegate:
public delegate string MyGenericDelegate<T1,T2>(T1 a,T2 b); MyGenericDelegate<double,double> genericDel=new MyGenericDelegate<double,double>(add)
Func Delegate in C#
The Func delegate is a delegate included in the System namespace. They are used for value returning methods. They must accept a minimum of 0 and a maximum of 16 parameters and at least one output parameter. Programmers do not need to explicitly declare a custom delegate if they are using the Func delegate.
Now, we will modify the example that we used earlier in the lambda expression section so that it can return a value.
namespace MyApplication { delegate double ArithmeticOperation(double operand1, double operand2); class Example { static double Multiply(double number1, double number2) { return number1 * number2; } static void Main(string[] args) { ArithmeticOperation mul = Multiply; var result = sum(4, 3); Console.WriteLine(result); } } }
If you are using the Func delegate, then you do not need to use the following custom delegate:
delegate double ArithmeticOperation(double operand1, double operand2);
Instead, use the assignment shown below:
Func<double,double,double> mul = Multiply;
With this, our code should look like the following:
class Example { static double Multiply(double number1, double number2) { return number1 * number2; } static void Main(string[] args) { Func<double,double,double> mul = Multiply; var result = mul(4, 3); Console.Write(result); } }
I hope this post helped you to understand the concept of delegates and anonymous functions. Happy Coding!
Read more C# programming tutorials.