Introduction
A delegate is a reference type and a type safe function pointer that references methods using their memory addresses and invoke them dynamically during run time of the program. A delegate has a specified set of parameters and a return type like a method and it invokes a method that has the matching parameters and a return type. It means that the parameters and the return type of a delegate must be the same as the parameters and the return type of a method it references to. An instance of a delegate takes a method as a parameter and references it using its memory address. To invoke a method using a delegate, first we define a custom delegate reference type using the delegate keyword and declare its parameters list and a return type according the target method then we declare an instance from it and instantiate it by assigning the target method to it as parameter. When a method is assigned as parameter to an instance of the delegate reference type, it stores the memory address of that method and invokes it dynamically during runtime of the program. An instance of the delegate invokes either a static method associated with a class or an instance method associated with an object. A delegate reference type is similar to other reference types but the main difference is that other reference types hold the references or the memory addresses of variables and a delegate reference type holds the reference or the memory address of a method like a function pointer in C++ programming language.
A delegate is similar to the function pointers in C++ programming language. The function pointer of C++ programming language is a pointer variable that points to a function using its memory address. To invoke a function using a function pointer, we simply assign the memory address of the method to the function pointer variable and invoke it using its memory address. A function pointer variable in C++ is a pointer variable but its declaration is similar to the function declaration that has the matching parameters list and a return type with the parameters list and the return type of the function that points to it. Therefore, a function pointer variable in C++ programming invokes a function that has the matching parameters a return type. The main difference between the C++ function pointers and the delegates is that the C++ function pointer holds only the memory address of a function and it does not carry any additional information such as the number of parameters used by the function, the types of the parameters, and the return type of the function while a delegate holds the memory address of a method and carry all the information associated with the method we want to invoke and also can access any variable visible to the enclosing scope. The delegates are actually the .NET implementation of functions pointers and they are object-oriented, type safe and secure unlike C++ functions pointers. Therefore, we can say that delegates are the .NET reference objects which can be used to invoke methods of matching signatures and return type. A delegate invokes a method synchronously and asynchronously and it can also be used to define callback methods. A callback method is a user-defined method that is used to process the result of an asynchronous operation in a separate thread.
Invoke Methods using Delegates
To invoke a method using a delegate, we must follow the following three steps:
- The Declaration of Delegate Type
- The Instantiation of Delegate Instances
- The Invocation of Method
The Declaration of Delegate Type
The declaration of the delegate defines a custom delegate reference type using a keyword delegate. A delegate reference type has a specified set of parameters and a return type according to the method it references to. A delegate reference type can be declared within the scope of a namespace or within the scope of a class. We cannot declare a delegate as a data member of a class and we cannot declare it as a local variable within the scope of a method because the declaration of a delegate is actually a new type definition and types can be defined only within the scope of a namespace and within the scope of a class. We cannot define any type within the scope of a method. Following is the general syntax to define a delegate reference type:
C# Syntax
[Modifiers] delegate ReturnType DelegateName([ParameterList]);
Visual Basic.NET Syntax
[Modifiers] Delegate Function DelegateName([ParameterList]) As ReturnType
The declaration of a delegate type usually has five parts such as modifiers, the delegate
keyword, return type, the delegate name, and a list of parameters. The first part of a delegate declaration is [Modifiers]
that indicates an access modifier. The access modifiers are keywords used to specify the declared accessibility of a member or a data type. The main and important access modifiers are public
, protected
, private
, and internal
modifiers. The second part of the delegate declaration is a delegate
keyword. A delegate
keyword is a reserved word provided by the .NET Framework that is used to declare a delegate reference type. The third part of the delegate declaration is ReturnType
that indicates the return type of the delegate reference type. The return type of the delegate reference type must be the same as the return type of the method we want to invoke. The fourth part of the delegate declaration is the DelegateName
that indicates a user-defined name of the delegate reference type we want to declare. The user-defined name of a delegate reference type must follow the variables and methods naming convention of the .NET Framework. The fifth part of the delegate declaration is [ParameterList]
that indicates the number of parameters of a delegate reference type. The parameters list of the delegate reference type must be the same as the parameters list of the method we want to invoke.
The Instantiation of Delegate Instances
The instantiation of a delegate instance is a process in which an instance of a delegate is referenced or associated with a method that has the matching parameters and a return type. A method can be referenced or associated with an instance of the delegate by assigning that method to it as parameter. When we define a custom delegate reference type using a delegate keyword then we declare an instance from it and instantiate it by assigning the target method to it as parameter. When the method is assigned as a parameter to an instance of the delegate, it stores the memory address of that method and the method is referenced or associated with it. Following is the general syntax to declare and instantiate an instance of a delegate reference type:
C# Syntax
DelegateName instanceName = null;
instanceName = new DelegateName(MethodName)
Visual Basic.NET Syntax
‘Declare an instance of the Delegate reference type
Dim instanceName As DelegateName = Nothing
‘Instantiate an instance of the Delegate reference type
instanceName = New DelegateName(AddressOf MethodName)
The above declaration declares and instantiates an instance of the delegate reference type. The name of the declared instance is instanceName
. The DelegateName
indicates the name of the delegate reference type from which we declare an instance instanceName
. The new
keyword is used to instantiate the instance of the delegate reference type. The MethodName
indicates the name of the method we want to invoke.
The Invocation of Methods
When a method is referenced or associated with an instance of the delegate then this is the last step in which we invoke that method by calling the associated instance of the delegate and assign values to its parameters, if the referenced or associated method takes parameters. Following is the general syntax to invoke a method using the referenced or associated delegate instance:
C# Syntax
ReturnType instanceName(ParametersList);
Visual Basic.NET Syntax
ReturnType instanceName(ParametersList)
In the above declaration the ReturnType represents the return type of the referenced or associated method, the instanceName represents the name of the delegate instance, and the ParametersList represents the number of parameters of the referenced or associated method.
Types of Delegates
The delegates are categorized into the following two types:
- Single Cast Delegates
- Multicast Delegates
Single Cast Delegates
A single cast delegate is a type of delegate that references to a single method at a time. A single cast delegate holds the reference or the memory address of a single method that has the matching parameters and a return type. Following is an example of a single cast delegate type definition:
C# Example of Delegate type definition
public delegate int myDelegate(int x);
Visual Basic.NET Example of Delegate type definition
Public Delegate Function myDelegate(x As Integer) As Integer
The above declaration defines a delegate reference type myDelegate. The myDelegate is a user-defined name of the delegate reference type that takes a single integer parameter and returns an integer value. Therefore, the myDelegate reference type references and invokes a method that takes a single integer parameter and returns an integer value.
Program # 1
Write a program that invokes a simple static
method using a delegate and displays a message in the method body. The method has no parameters list and no return type.
C# Program
using System;
namespace ProgramNamespace
{
public delegate void dlgMessage();
public class MainProgramClass
{
static void Main(string[] args)
{
dlgMessage instDelegate = null;
instDelegate = new dlgMessage(displayMessage);
instDelegate();
Console.WriteLine("Press any key to exit program");
Console.ReadKey();
}
public static void displayMessage()
{
Console.WriteLine("Welcome to the .NET Delegates");
}
}
}
VB.NET Program
Namespace ProgramNamespace
Public Delegate Sub dlgMessage()
Public Class MainProgramClass
Public Shared Sub displayMessage()
Console.WriteLine("Welcome to the .NET Delegates")
End Sub
Public Shared Sub Main()
Dim instDelegate As dlgMessage = Nothing
instDelegate = New dlgMessage(AddressOf displayMessage)
instDelegate()
Console.WriteLine("Press any key to exit program")
Console.ReadKey()
End Sub
End Class
End Namespace
Program # 2
Write a program that invokes a non static
method of a class using a delegate. The method has no parameters list and it return a string
message to its calling point.
C# Program
using System;
namespace MainProgramNamespace
{
public delegate string dlgMessage();
public class MyMethodClass
{
public string displayMessage()
{
return "Welcome to the .NET Delegates";
}
}
public class MainProgramClass
{
static void Main(string[] args)
{
MyMethodClass obj = new MyMethodClass();
dlgMessage instDelegate = null;
instDelegate = new dlgMessage(obj.displayMessage);
string msg = instDelegate();
Console.WriteLine(msg);
Console.WriteLine("Press any key to exit program");
Console.ReadKey();
}
}
}
Visual Basic.NET Program
Namespace MainProgramNamespace
Public Delegate Function dlgMessage() As String
Public Class MyMethodClass
Public Function displayMessage() As String
Return "Welcome to the .NET Delegates"
End Function
End Class
Public Class MainProgramClass
Public Shared Sub Main()
Dim obj As New MyMethodClass()
Dim instDelegate As dlgMessage = Nothing
instDelegate = New dlgMessage(AddressOf obj.displayMessage)
Dim msg As String = instDelegate()
Console.WriteLine(msg)
Console.WriteLine("Press any key to exit program")
Console.ReadKey()
End Sub
End Class
End Namespace
When the above program executes, then it displays a message “Welcome to the .NET Delegates”. The program contains a delegate reference type dlgMessage
and a method displayMessage
. The delegate reference type dlgMessage
is a parameter-less delegate reference type that does not take any parameter and its return type is string
that returns a string
value. The method displayMessage
is a parameter-less user-defined method we defined in a separate class MyMethodClass
. The user-defined method displayMessage
returns a message “Welcome to the .NET Delegates”. The parameter and the return type of the delegate dlgMessage
and the parameter and the return type of the method displayMessage
are the same because both the method and delegate reference type do not take any parameter and both have a string
return type. In the main method of the program, we also declared an instance of the delegate reference type. The name of the delegate reference type instance is instDelegate
. The instance instDelegate
is used and invokes the method displayMessage
that returns a string message “Welcome to the .NET Delegates”.
Program # 3
Write a program that invokes a non static
method of a class using a delegate. The method takes two integer parameters and returns their sum to its calling point.
C# Program
using System;
namespace ProgramNamespace
{
public delegate int calculateTwoValues(int x, int y);
public class MyMethodClass
{
public int addValues(int x, int y)
{
return (x + y);
}
}
public class MainProgramClass
{
static void Main(string[] args)
{
MyMethodClass obj = new MyMethodClass();
calculateTwoValues instDelegate = null;
instDelegate = new calculateTwoValues(obj.addValues);
int sumValue = instDelegate(10, 20);
Console.WriteLine(sumValue);
Console.WriteLine("Press any key to exit program");
Console.ReadKey();
}
}
}
Visual Basic.NET Program
Namespace ProgramNamespace
Public Delegate Function calculateTwoValues(x As Integer, y As Integer) As Integer
Public Class MyMethodClass
Public Function addValues(x As Integer, y As Integer) As Integer
Return (x + y)
End Function
End Class
Public Class MainProgramClass
Public Shared Sub Main()
Dim obj As New MyMethodClass()
Dim instDelegate As calculateTwoValues = Nothing
instDelegate = New calculateTwoValues(AddressOf obj.addValues)
Dim sumValue As Integer = instDelegate(10, 20)
Console.WriteLine(sumValue)
Console.WriteLine("Press any key to exit program")
Console.ReadKey()
End Sub
End Class
End Namespace
When the above program executes, then it displays the sum of two integer values and displays the result. The program contains a delegate reference type calculateTwoValues
and a method addValues
we defined in a separate class MyMethodClass
. The delegate reference type calculateTwoValues
takes two integer parameters and return an integer value. The method addValues
also takes two integer parameters and returns an integer value. The parameters and the return type of the delegate calculateTwoValues
and the parameters and the return type of the method addValues
are same because both the method and the delegate reference type take two integer parameters and return an integer value. In the main method of the program, we declared an instance of the delegate reference type. The name of the delegate reference type instance is instDelegate
. The instance instDelegate
instance passed two integer values from the main method of the program and invokes the method addValues
. The method addValues
calculates the sum of the two received values and returns the result back to the main method of the program. In the main method of the program, we declared an integer variable that stores the result of the method.
The Multicast Delegates
A multicast delegate is a type of the delegate that references and invokes multiple methods at the same time. An instance of the multicast delegate reference type holds the references or the memory addresses of multiple methods which have the same parameters lists and the same return types as the parameters list and the return type of that of the delegate reference type. It means that the methods we want to invoke by using multicast delegate must have matching parameters and return types with the delegate reference type. The declaration of a multicast delegate and a single cast delegate is the same but the main difference is that an instance of a single cast delegate reference type references and invokes a single method at a time whereas an instance of a multicast delegate reference type reference and invokes multiple methods at the same time. The multicast delegate reference type is derived from the MulticastDelegate class that represents a multicast delegate type. The multicast delegate provides two operators i.e. += operator and -= operator which are used to add and remove the reference of a method respectively to the instance of the multicast delegate reference type. The multicast delegate holds the reference of a methods with a += operator and removes the reference of a method with -= operator. Following is an example of a multicast delegate type definition:
C# Example of Delegate Type Definition
public delegate void myDelegate(int x);
Visual Basic.NET Example of Delegate Type Definition
Public Delegate Sub myDelegate(x As Integer)
The above declaration defines a delegate type myDelegate. The myDelegate is a user-defined name of the delegate that takes a single integer parameter and its return type is void that does not return any value. The above delegate myDelegate is a multicast delegate type that references and invokes multiple methods at the same time.
Program # 3
Write a program that invokes multiple methods using a multicast delegate. Declare three methods in a class and invoke these methods using a delegate from the main method of the program. The methods take two integer parameters and they do not return any value. The first method takes two integer values and calculates their sum.
The second method takes two integer values and calculates their subtraction and the third method takes two integer values and calculates their multiplication.
C# Program
using System;
namespace ProgramNamespace
{
public delegate void calculateTwoValues(int x, int y);
public class MyMethodClass
{
public void AddValues(int x, int y)
{
Console.WriteLine("The sum of two values is");
Console.WriteLine(x + y);
}
public void SubtractValues(int x, int y)
{
Console.WriteLine("The subtraction of two values is");
Console.WriteLine(x - y);
}
public void MultiplyValues(int x, int y)
{
Console.WriteLine("The multiplication of two values is");
Console.WriteLine(x * y);
}
}
public class MainProgramClass
{
public static void Main()
{
MyMethodClass obj = new MyMethodClass();
calculateTwoValues instDelegate = null;
instDelegate += new calculateTwoValues(obj.AddValues);
instDelegate += new calculateTwoValues(obj.SubtractValues);
instDelegate += new calculateTwoValues(obj.MultiplyValues);
instDelegate(5, 2);
Console.WriteLine("Press any key to exit program");
Console.ReadKey();
}
}
}