August 24, 2021 06:39 by
Peter
Why use delegate in C#?
Delegate is one of the most incorrectly-interpreted words by developers in C#. Delegate is widely used inside .net framework itself. Let’s go further and break down that delegate question that every interviewer asks.
My Experience with Delegates
In my all years of experience I have used delegate several times and noticed that after I am done with development who ever over takes that code from me is not able to grasp that particular delegate logic.
If used wisely it can save a lot of time and lines of code but if used in inappropriately it will confuse everyone in the future.
Purpose
It helps achieve the following,
Encapsulation / Abstraction
Security
Callback
Re-usability
Most common definition of Delegate,
“Delegate is a keyword in .net that is used as function pointer” or
“Delegate is used for callbacks only”
Well nothing is wrong with these definitions but they don't tell you the whole picture.
Characteristics
Delegate has a few characteristics:
Type safe
Takes method in assignment
Let’s start by an example,
First let’s create our Product model
We are going to use this model
using System;
namespace Models
{
public class Products
{
public string ProductName { get; set; }
public int ProductId { get; set; }
}
}
Let’s create and interface
General practice to create interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLayer
{
public interface ICustomer<T>
{
void Process(T products);
}
}
Second, inherit this interface in class
using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLayer
{
public class FrequentCustomer : ICustomer<Products>
{
public void Process(Products product)
{
Console.WriteLine($"Product Count : 1");
Console.WriteLine("--Product Details--");
Console.WriteLine($"Name : {product.ProductName} Product Id : {product.ProductId}");
}
}
}
Process is the method which will be called by an anonymous later
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServiceCallManager
{
public static class ServiceCaller
{
public static void Invoke<TService>(Action<TService> action)
{
Type typ = typeof(TService);
TService instance = (TService)Activator.CreateInstance(typ);
action(instance);
}
}
}
Invoke is the method which takes Action<TService> type argument, in .Net Action delegate's return type is void.
See the summary, it says “encapsulates.”
Now we all know delegate takes method in assignment (Encapsulates method)
Method can be in any form, let’s say anonymous methods.
What is the anonymous method?
“A method without a name!”
Now let’s look into our next class.
class Program
{
static void Main(string[] args)
{
IList<Products> products = new List<Products>();
Products product1 = new Products();
product1.ProductName = "Rice";
product1.ProductId = 1;
products.Add(product1);
product1 = new Products();
product1.ProductName = "Bread";
product1.ProductId = 2;
products.Add(product1);
product1 = new Products();
product1.ProductName = "Pasta";
product1.ProductId = 3;
products.Add(product1);
ServiceCaller.Invoke<FrequentCustomer>(x => x.Process(product1));
Console.WriteLine();
Console.ReadKey();
}
}
ServiceCaller.Invoke<FrequentCustomer>(x => x.Process(product1));
Remember that the invoke method accepts delegate as argument and delegate encapsulates methods, so here inside Invoke method I am passing an anonymous method which will get invoked when action() is called which executes the anonymous method and calls the Process method of FrequentCustomer class.
Let’s go step by step,
Breakpoint comes to ServiceCaller.Invoke<FrequentCustomer>(x => x.Process(product1));
It goes inside Invoke method of staticServiceCaller class
Via reflection we are creating object of ServiceT type (You can ignore this if you don’t understand reflection)
At the last line of method action is called with parameter instance; i.e. object of ServiceT type
After action (instance) is called breakpoint comes to ServiceCaller.Invoke<FrequentCustomer>(x => x.Process(product1)); and it starts executing the x => x.Process(product1) part only
You will notice that x is of type FrequentCustomer
So this part of execution calls the Process method or FrequentCustomer and is also passing local parameter in it.
Now the benefit of delegate here is I am able to use local variable inside method; i.e. product1, which may not be available in other class due to security reasons.
Delegate helps me implement Encapsulation, Security, Callback (Obviously), Re-usability and if used wisely, Polymorphism also.
European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.