Advanced using of delegates in C# - Part II
In first article about the delegates, I tried to explain, basic concept of
delegates, and how it could be used.
In this article I shall present you the use of delegates in real world situations!
If you liked concept of delegates in my previous article, feel free to keep on reading! :)
Define delegate and filtering methods
Try imagine you have a list of persons (in this case developers), where every developer use some technology. Based on these technologies, you want to filter developers in three groups: web, desktop, and database developer. You can achieve this in very ellegant way using delegates.
First we create Developer class which will define the data we want to store.
class Developer
{
public string FullName { get; set; }
public string Technologies { get; set; }
}
We shall use this class in generating some data in generic list, but for now, this piece of code will be enough.
Next thing we shall do is to define delegate.
// Define delegate
public delegate bool FilterDevelopers(Developer developer);
Delegate is "just the signature" for filter methods, which receives Developer type object as parameter.
Based on that delegate, we create three methods that do all the filtering!
/// <summary>
/// Returns bool if developer is WEB developer...
/// </summary>
public static bool Is_Web_Developer(Developer developer)
{
return developer.Technologies.Contains("ASP.NET") ||
developer.Technologies.Contains("HTML") ||
developer.Technologies.Contains("MVC") ||
developer.Technologies.Contains("CSS");
}
/// <summary>
/// Returns bool if developer is DESKTOP developer...
/// </summary>
public static bool Is_Desktop_Developer(Developer developer)
{
return developer.Technologies.Contains("Windows Forms") ||
developer.Technologies.Contains("WPF") ||
developer.Technologies.Contains("MVVM");
}
/// <summary>
/// Returns bool if developer is DATABASE developer...
/// </summary>
public static bool Is_Database_Developer(Developer developer)
{
return developer.Technologies.Contains("SQL Server");
}
This is easy: if developer works with specific technology, we shall return true, which means that he belong to specific type of developer.
Next, we shall combine that piece of code with some additional code to make things work.
Make use of delegates
We create generic list and fill it with names and list of technologies for every person. After creating list, we send that data to method called "DisplayDevelopers" with funtion as parameter, based on which we will make data-filtering.
static void Main(string[] args)
{
// Generating some data...
List<Developer> developers = new List<Developer>()
{
new Developer(){ FullName = "Matija Božičević", Technologies = "C#, .NET, ASP.NET, SQL Server, WPF, MVVM, MVC, HTML, CSS" },
new Developer(){ FullName = "John Developer", Technologies = "C#, Windows Forms, WPF" },
new Developer(){ FullName = "Michael Developer", Technologies = "SQL Server" },
new Developer(){ FullName = "Dough Developer", Technologies = "ASP.NET, HTML, CSS" }
};
// ************************************************************************
// The "DisplayDevelopers" is method that does all the procesing of methods!
// ************************************************************************
// Call method to write out specific developer based on "filter function"
DisplayDevelopers(developers, Is_Web_Developer);
DisplayDevelopers(developers, Is_Desktop_Developer);
DisplayDevelopers(developers, Is_Database_Developer);
// Just pause the app...
Console.ReadKey();
}
/// <summary>
/// Method that receives some data, and filters it based on the received parameter-like method
/// </summary>
static void DisplayDevelopers(List<Developer> developers, FilterDevelopers filter)
{
foreach (Developer developer in developers)
{
// Parameter "filter" is basically just the placeholder for method we forwarded.
// Because, all methods "Is_..." are returning bool, we just put this in "if" statemant.
// NOTE: in compile time we don't know which method will be used here.
// We only know that HERE, we must call method passed as parameter, and send her some data, in this case "developer" object.
if (filter(developer))
{
// Some trick with reflection and ".Method.Name...", for using method names as readable text
Console.WriteLine(string.Format("{0} {1}!", developer.FullName, filter.Method.Name.Replace("_", " ").ToLower()));
}
}
Console.WriteLine(new string('-', 45));
}
Method DisplayDevelopers filters the data based on "filter" parameter and writes some output text:
Matija Božičević is web developer!
Dough Developer is web developer!
---------------------------------------------
Matija Božičević is desktop developer!
John Developer is desktop developer!
---------------------------------------------
Matija Božičević is database developer!
Michael Developer is database developer!
---------------------------------------------
This was the advanced example of how to use delegates in real world situations.
It's not easy for begginers to understand what we did here, but when you put all the pieces together, using delegates makes a lot of sense!
The more complex filtering (or other algorythm's) in "Is_..." functions, the more meaning delegates have!!