In C#, what is a delegate? A delegate is an object that knows how to call a method or a group of methods. Another way of saying that is a delegate is a reference (or a pointer) to a function. We can use a delegate that becomes responsible for calling methods for us. A more specific definition is a delegate is a pointer to a method with a specific signature.
Why do we need to use delegates? This allows us to create applications that are extensible and flexible. One example is the designing of frameworks.
Photos Program Example by Mosh
A good way to understand delegates is to use an example. We will use the example that Mosh Hamedani used in his Udemy.com video called C# Advanced Topics: Prepare for Technical Interviews. In this post we will set up the example and in the next post we will create delegates.
In our application, we are responsible for designing a framework for processing photos. We load the photo and apply several filters and transformations to the photos. We will create a class called Photo that represents a single photo. We will have a class called PhotoProcessor that has one method called Process() that takes as a parameter the path to the photo, loads the photo and applies a set of filters to the photo, and finally Saves the photo. To simplify this we will just write to the console when we apply a filter or transformation to avoid the complexities of actually doing these things.
namespace Photos { class Program { static void Main(string[] args) { var myProcess = new PhotoProcessor(); myProcess.Process("pic.jpg"); Console.ReadKey(); } } }
Our PhotoProcessor. This code below has a limitation. We have three filters that we have included in our framework. What if we write some more filters? We could release the code for that in another version, but the users of our framework would need to download it and install it. So we would need to recompile and re-deploy the code. What if developers could create their own filters?
namespace Photos { class PhotoProcessor { public void Process(string path) { var photo = Photo.Load(path); var filters = new PhotoFilters(); filters.ApplyBrightness(photo); filters.ApplyContrast(photo); filters.Resize(photo); photo.Save(); } } }
Our Photo class.
namespace Photos { class Photo { public static Photo Load(string path) { return new Photo(); } public void Save() { } } }
Below is our collection of filters. All we need to do right now is send a message to the console to let us know that the filter has been applied.
namespace Photos { class PhotoFilters { public void ApplyBrightness(Photo photo) { Console.WriteLine("Apply brightness"); } public void ApplyContrast(Photo photo) { Console.WriteLine("Apply contrast"); } public void Resize(Photo photo) { Console.WriteLine("Resize"); } } }