Introduction
There are many articles and blogs about delegates in the .Net Framework. I just thought to share the use of delegates and where to use them in actual projects. I shall start with a very simple console application where I have used delegates.
Before going through this article I recommend you get some knowledge of Delegates. There are many articles and blogs in c-sharpcorner.com.
Step 1: Create a Student Class
Student.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace CustomDelegates
{  
    public class Student
    {
        public int RollNo { get; set; }
        public string StudentName { get; set; }
        public int Marks { get; set; }
        public bool hasSportsQuota {get;set;}       
    }
}
Step 2: Create a StudentDelegate Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace CustomDelegates
{
    public delegate bool DisplayEligibleStudents(Student student);
    public static class StudentDelegate
    {
        public static void EligibleStudenList(List<Student> lstStudents, DisplayEligibleStudents eligibleStudents)
        {
            foreach (Student student in lstStudents)
            {
                if (eligibleStudents(student))
                {
                    Console.WriteLine("Roll No : {0} , Name : {1}",student.RollNo,student.StudentName);
                }
            }
        }
    }
}
Explanation
In a normal coding scenario we write some custom login inside the function EligibleStudentList.
For example:
public static void EligibleStudenList(List<Student> lstStudents)
{
    foreach (Student student in lstStudents)
    {
        if (lstStudents.Mark>75)
        {
            Console.WriteLine("Roll No : {0} , Name : {1}",student.RollNo,student.StudentName);
        }
    }
}
The logic is correct and the application works as expected. 
Scenario: Customer wants to display all students based on varying criteria. 
In this situation normally we go and rewrite the logic inside the preceding function but that is a bad approach. Here comes the role of delegates.
It would be really great if the criteria are passed as a parameter to our function EligibleStudentList.
Delegates Methodology
I have created a delegate named DisplayEligibleStudents that takes an input of type Student class and returns a Boolean value.
EligibleStudentList function takes 2 input:
- List<Student> 
- DisplayEligibleStudents (Our Custom Delegate). 
Step 3: Main Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace CustomDelegates
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Eligible Students....");
            Console.WriteLine("**********************************************************");
 
            // Intializing the student properties.
            Student student1 = new Student { RollNo = 1001, StudentName = "Madhav", Marks = 97, hasSportsQuota = true };
            Student student2 = new Student { RollNo = 1004, StudentName = "Rachel", Marks = 89, hasSportsQuota = false };
            Student student3 = new Student { RollNo = 1009, StudentName = "John", Marks = 45, hasSportsQuota = true };
            Student student4 = new Student { RollNo = 1002, StudentName = "James", Marks = 66, hasSportsQuota = true };
            Student student5 = new Student { RollNo = 1003, StudentName = "Nike", Marks = 48, hasSportsQuota = false };
 
            //Create a List of Students: 
            List<Student> lstStudents = new List<Student>();
            lstStudents.Add(student1);
            lstStudents.Add(student2);
            lstStudents.Add(student3);
            lstStudents.Add(student4);
            lstStudents.Add(student5); 
            
            //Eligible criteria is marks >75
            Console.WriteLine("Eligible Criteria : Marks > 75 ");
            Console.WriteLine("**********************************************************");
            StudentDelegate.EligibleStudenList(lstStudents, e => e.Marks > 75);           
 
            //Eligible Critertia is : Has Sports Quota
            Console.WriteLine("Eligible Criteria : Students with Sports Quota");
            Console.WriteLine("**********************************************************");
            StudentDelegate.EligibleStudenList(lstStudents, e => e.hasSportsQuota==true); 
            Console.ReadLine();
        }
    }
}
I have provided some comments in the code. Please refer to them.
Without changing the program logic different criteria are passed to the EligibleStudentList function.
Output
![Use of Delegates]()
By using delegates the actual logic inside the function is never changed even when there is a new change request made by the customer.
Happy Coding...