A delegate in C# is a type-safe function pointer that can point to one or more methods with compatible signatures. Here, the term compatible signature implies that the signature of the delegate – and the method it points to – are the same. A function signature consists of the function name, type and sequence of parameters, and return type. This C# programming tutorial covers the concept of delegates, how they work, and how developers can program delegates in C#.
Read: Working with Generics in C#
What is a Delegate in C#?
Delegates are object-oriented, type-safe, and secure function pointers. Using a delegate, developers can call a method whose call can only be resolved or determined at runtime. Delegates can be used to define callback methods and implement event handling.
A delegate object encapsulates a static method or a class instance and an instance method of that class. This makes it possible for the delegate to invoke either the static method or the instance method.
What are the Advantages of Delegates?
As you may have noticed, delegates have a number of advantages over function pointers in C and C++. They include:
- Delegates are managed and type-safe and can invoke both static and non-static methods.
- Chaining of delegate methods is possible; for example, multiple methods can be called on one event.
- Programmers can use delegates to define callback methods.
- Delegates can be passed as parameters to methods.
Read: C# Tools for Code Quality
What is the Syntax of Delegates in C#?
The general syntax used to declare a delegate is as follows:
delegate [return type] nameofDelegate ([parameters]);
In the above example, the return type is void and there are no parameters. In its most basic form, a delegate could be declared as follows:
delegate void MyDelegate();
What are Delegates Used for in C#?
Delegates are used in C# to perform callbacks. A callback is a function that passes control from one part of a program to another. An example of this is when you click a button on a web page; the browser sends an HTTP request to the web-server and then waits for the web-server to return with information by executing the code in the callback function. Delegates are also used in events. When you subscribe or listen to an event, it is actually subscribing or listening to a delegate which can then be invoked and executed after that specific event has occurred.
Programmers can use delegates in the following situations:
- When developers want to define a method that has the same parameters as that of some other method.
- When you want to pass methods as arguments to other methods.
- To implement events and callbacks or to implement runtime polymorphism.
What are the Downsides of C# Delegates?
While the usage of delegates has several benefits, there are certain downsides as well. In certain situations, the limitations of delegates may make them less than ideal.
Here are a few downsides of using delegates in C#:
- A delegate can be slower to execute than a regular method because the Common Language Runtime (CLR) must first resolve a method reference before invoking it.
- When an exception is thrown in a method pointed to by a delegate, the stack trace does not tell what caused the exception, so debugging it is more complicated.
- Delegates are a weaker contract than other types of associations. This is because you can do anything with the delegate as long as the delegate’s signature is identical to the method it needs to point to.
- The use of delegates can also make your code fragile. Excessive usage of delegates hinders readability. You can change the name of any delegate without having to change the method name that it points to.
- The JIT compiler and the runtime can do much less optimization with delegates than they can do with normal functions. Hence, calling methods using delegates is slower than calling those methods directly.
How to Program Delegates in C#
The following code example illustrates a single-cast delegate in C#:
using System; public delegate void SingleCastDelegate(string message); class Example { public static void DisplayText(string message) { Console.WriteLine(message); } static void Main() { SingleCastDelegate delegateObj = new SingleCastDelegate(DisplayText); delegateObj("Hello World!"); Console.ReadLine(); } }
Note how the delegate is declared outside of the class and then instantiated in the Main method. Also, note that the signatures of the delegate and the method it is pointing to are identical.
Let us now create another method named DisplayMessage in the same class:
public static void DisplayMessage(string message) { Console.WriteLine(message); }
Note that the signature of the DisplayMessage method is the same as the delegate we created earlier.
You can instantiate the multicast delegate as shown in the code snippet below:
static void Main() { MulticastDelegate obj1 = new MulticastDelegate(DisplayText); MulticastDelegate obj2 = new MulticastDelegate(DisplayText); obj1 = obj1 + obj2; // Make obj1 a multi-cast delegate obj1("Hello World!"); //Invoke delegate Console.ReadLine(); }
The statement obj1 = obj 1 + obj2 makes obj1 a multicast delegate. Here is the complete program for your reference:
using System; public delegate void MulticastDelegate(string message); class Example { public static void DisplayText(string message) { Console.WriteLine(message); } public static void DisplayMessage(string message) { Console.WriteLine(message); } static void Main() { MulticastDelegate obj1 = new MulticastDelegate(DisplayText); MulticastDelegate obj2 = new MulticastDelegate(DisplayText); obj1 = obj1 + obj1; // Make t1 a multi-cast delegate obj1("Hello World!"); //Invoke delegate Console.ReadLine(); } }
Read: Productivity Tools for .NET Developers
Points to Remember
Here’s a list of the points we covered in this C# programming tutorial:
-
- You can use delegates to create callback methods.
- Delegate is a reference type data type. It holds the reference of one or more methods at a time.
- Delegates are used to define events and event handlers.
- All delegates are implicitly derived from the System.Delegate class.
- Delegates in C# are similar to function pointers in C++; however, delegates are type-safe function pointers.
Final Thoughts on C# Delegates
Read more C# programming and software development tutorials.