I’m getting into really understanding about delegates and thought I’d share my thoughts around this. I’m just touching the surface, but event driven development is something I’ve wanted to do for sometime. In this basic tutorial I’m trying to address the following simple problem.
“I would like to work out if one value is greater or less than another”
So this is easy, right? Just plug these methods in
The really bright ones could do it in one method but what if I wanted to define the operator at runtime or I wanted to store the business logic around how the first and second values interact with each other in a separate place to help code maintainability?
Delegates are what you need.
There are plenty of explanations around what delegates are which are probably much better than mine but here is my take on them. Part of the reason why I didn’t get delegates for sometime is around how much .net hides from you when you start developing.
Here are a few explanations I’ve seen recently
– Delegates are a pipeline through which data can move from one place to another.
– Delegates convert a method into a type or class and wrap around this method ie promote a method to act like a class or assign a pointer to a method.
– Delegates allow some other method to manage the data within the initial object. You are offloading or delegating responsibility of logic to another part of the programme. (hence the word delegation).
– Delegates don’t change data per se, they just help something else (eg another method in another object) manage how they are manipulated but the send and return types must be the same for all implemented methods.
– If you know Interfaces, Delegates are to Methods as to what Interfaces are to Classes.
– Delegates need a start point, an invoker (creator) and an end point which can be in separate classes.
They are essential in Events which are a type of custom delegate which returns void and takes an object (sender) and another container class called EventArgs which can be used to carry extra information. Event are another topic altogether but are fundamental and evolve from knowledge around delegates.
I think just the word Lambda shied me away from them. I had ideas of Greek notation and complex explanations around how Lambdas work but here is my one liner take on Lambdas
Lambdas are a short hand notation to create in line code of delegate method calls
As with all things, they can get quite complex especially when you start using LINQ but just have the above concept in mind. I thinks this is best described in an example, and for you to understand we need to work a bit backwards.
Defining your Pipeline/Delegate
Taking the above example I want to create a pipeline/delegate which will take 2 values and return true or false, what I do with the values is up to me but the actual data moving back and forth will be 2 doubles through and a bool back. So you’d define your delegate like this
I’m telling the compiler this delegate/pipeline will take 2 doubles and return a bool
So I’ve turned my method into a class or type and whenever I need to activate the pipeline I need to new the delegate.
So I have this data running down the pipeline, in the above example I’d like to handle this data and do something with it. I want to have 2 scenarios: one where I’m looking to see if one value is greater than the other and the second to see if one value is less than the other.
I have the option to invoke 2 types of delegates which both take the same data (2 doubles) and return a bool. One will see if it’s greater and other if it’s less than.
Here is where we use Lambdas. Let me break this down – I’ve put these delegate handlers or managers in a separate class to show how we can separate out the code. This would form the basis of business layer.
x and y, where did they come from and how does the compiler know what they are? If you noticed the delegate above already has the information to understand what the x and y is. In essence the delegate defines the footprint which takes 2 doubles (double, double) and returns bool so I don’t need to insert the value types. The doubles and bool are inferred from the delegate. We use x and y because we are lazy, we could have easily written it another way.
– within the squiggly braces are the in line method. It’s just short hand for the following bit of code.
Start Point or Invoking
So we need a method which actually passes the values. In this examples I’ve wrapped it in a class.
Notice how we are treating the Delegate like a method and passing the 2 doubles to return a bool. The beauty of this code is that the OperatorHandlers handle the logic and depending on which type I instantiate will depend on whether there is a greater or less than operation performed on the 2 doubles. I’m thus managing how the values are manipulated at run time.
I then invoke the delegate with associated values to process with the following lines from my Main Class.
Enclosed is the final code. You can also find it here on GitHub