Delegates: one of the few unique aspects of .NET. How useful are they? Here’s a delegate declaration. The syntax can take some getting used to.
In order to use the Operation
delegate we’ll need some methods that match the double (double, double)
form.
There’s nothing special about that. Now to create an instance of the Operation
delegate.
Again the syntax can throw you off a bit. This line instantiates an instance of Operation
with the Add
method and stores it in a variable named math
. To use math
you invoke it as though you were calling a method.
Invoking math
, with parameters 1 and 2, actually called Add
with the same parameters, hence the result of 3. The oposite behavior can be achieved by using the Subtract
method instead of Add
.
Math
just delegated the call with parameters 1 and 2 to Subtract
and so the result was -1. So far this isn’t very useful.
We can wrap methods up in delegates and call methods through the delegate but that’s just a lot of extra work. The power of Delegates comes into play when you don’t know which method to use.
Assume this code was used in a bank system. A frequent action of a bank system is to adjust the balance of an account.
Notice that AdjustBalanceBy
takes an Operation
Which means it could be Add
, Subtract
, Multiply
, or Divide
to adjust the balance.
There might be operations we haven’t considered yet like applying interest. AdjustBalanceBy
could take care of that for us as long as we give it a delegate that calls ApplyInterest(double, double)
.
The code in AdjustBalanceBy
would never have to change and that’s exactly how the Open/Closed Principle says it should be. How would this be done without delegates? The Command Pattern would work great!
There’s a bit more code without delegates but we’re saved from the wacky syntax. Considering the extra language complexity of delegates, I feel the Command pattern has the upper hand here. Point for Command Pattern.!meta Delegates 0 - Command Pattern 1.
What about multicasting?
Delegates have this feature called multicasting that allows you to add multiple delegates together. Here’s an example:
When math
is called at the bottom, all four operations are performed. In this case it’s not particularly useful but for something like a button, where, when clicked, multiple actions need to take place, multicasting is very convenient. But what happens to all the return values?
Each of the methods combined in the math delegate above returns a value but math
can only return one value.
Interesting. Multicasted delegates only return one value from the combined execution. This suggests that multicasting should only be used when you don’t really care what the return values are.
The Command Pattern alone can’t compete with multicasting but along with his good buddy Composite, they’ve got things under control.
This version of Composite mimics the delegate’s handling of the return values but it could easily average them, store them in a list, or do whatever else your funny bone fancies.
Composite gives much more control over combined execution and so I say it earns another point for Command Pattern. !meta Delegates 0 - Command Pattern 2
Events
Oh gosh. Get a load of this syntax.
An intuitive interpretation: button.Click
- Telling the button that it was clicked button.Click +=
- Adding something to the clicking of the button…Huh? new System.EventHandler(SomeAction) - SomeAction
must be a method the fits the EventHandler
method form.
An instance of EventHandler
is created with SomeAction
. After those logical steps a developer concludes that Click
must be a public field (or property) of Button
of EventHandler
which is a delegate.
And the developer would be wrong! Click
is actually an Event. The declaration looks something like this:
The whole Event construct is rather silly because, as far as I can tell, it could just as easily be replaced with a public field (or property). 1 point deduction from delegates for flagrant misuse of syntax.