When learning about a new technique/tool, I think is it is important to ask the following questions:
- Why i.e. what problem does this technique I’m trying to learn about solve?
- What i.e. what are the concepts/ideas behind the technique?
- How i.e. what are the mechanics involved using the technique?
- When i.e. when is it appropriate to use the technique?
So the main reason why delegates are useful stems from the fact that they help with writing loosely coupled code. It is a bit difficult to explain this in detail until the “What” and the “How” are explained.
Hence, I will begin with item 2 i.e. the What.
What are delegates?
A lot of explanations I’ve read about what delegates are, involve the use of analogies e.g. Jon Skeet in his book C# in depth talks about the executor of a will; or as in the C# 3.0: Master the fundamentals of C# 3.0 book, the use of delegates in the “proper” sense of the word.
However, all analogies are just that and when they are probed hard enough, they fall apart. The difficulty lies in understanding what delegates are in the .NET context. Hence, I will try to explain in .NET terms what a delegate is.
The C# 3.0: Master the fundamentals of C# 3.0 book provides a very good starting point:
A delegate is a reference type, like the other reference types …, but instead of referring to an object, a delegate refers to a method
Let’s break down this definition in two parts:
- A reference type refers to an object.
- A delegate is also a reference type but one which points to a method.
If you’ve done any Object Oriented Programming, then the first part of this definition (reference types refer to an object) should make sense as the concept of a reference type should be clear to you (if not, you must understand this first).
Now consider the following code:
|public static void Eats()|
|// Some implementation|
|public static void Says(string message)|
|// Some implementation|
The following should make sense in the context of the first part of the definition:
var person = new Person();
In essence, our reference “person” refers to the “Person” object.
Now for one minute imagine that you could somehow just write the following:
var personEatsDelegate = Person.Eats;
If you ignore the fact that it is “
Person.Eats” and not “
Person.Eats()”, then similar to the previous code, the delegate “personEatsDelegate” refers to the method “Person.Eats” which is exactly the second part of the definition of delegates as given above.
So in .NET, delegates provide a mechanism to assign a method to a variable where that variable is of type “delegate”.
Now, the code as given will not compile because I’ve omitted important code which I’ll cover when dealing with the mechanics of delegates (declaring, instantiating and invoking). What I’ve shown here is only the instantiation aspect of delegates. However, once the declaration part is done, this code will compile.
The fact that a delegate is a reference type means that we can do the following:
var result = SomeClass.DoSomething(personEatsDelegate);
In other words, we’re passing a function around. You will be no doubt be more familiar with passing Objects or value types around like:
var result = SomeClass.DoSomething(person);
But the point I want to emphasise is that delegates are reference types albeit a bit special. The reason for this empashis will become clear in the mechanics of delegates section which will be my next post.