I did take an introductory session at work about threading in the .NET Framework a long time ago. And someone asked me about delegates... what is the actual use of a delegate?
My answers then were actually really blunt. My understanding, even now (and then), prompts/prompted me to say, it's a function pointer. Even Microsoft admits it is a function pointer, but further adds on to say that it is a type in the .NET programming framework which is more object-oriented, type-safe, and secure. It derives from the
Delegate class. It is an
abstract class, but it's also sealed. That means we cannot derive from it. This link should be a starting point for you to understand what delegates are if you want to take the journey on your own.
A function pointer is a concept usually equated with system programming languages like C or C++. They simply mean that they are a reference to a method that has a particular signature or a sequence of arguments/parameters. Actually it could refer to any method with the same sequence! So ultimately it gives you the freedom to programmatically assign an appropriate method and then invoke it.
So how do you utilize this concept? From a novice programmer's POV, it doesn't make a big deal. However if you were someone who designed compilers and stuff, it would matter. (I am not a compiler or someone who writes programs for compilers).
Function pointers I guess were introduced to implement a callback pattern. It makes more sense if you concurrently think of asynchronous programming patterns also.
Your program is a sequence of instructions. Only after one instruction completes, the next one is executed, and so on. This is commonly referred to as the synchronous pattern of execution. Imagine a particular instruction is a method call. The instruction pointer will hold the address of the next routine in the main program's code path; the execution flow is handed over to the subroutine and those instructions are executed. Once this routine returns, execution flow is handed back to the main code path and the next instruction is executed. So basically we have the 2nd instruction waiting to be executed until the 1st one finishes. So the 1st instruction makes the 2nd one wait. We refer to this phenomenon as blocking. Therefore we look forward for asynchronous patterns of program execution to obviate the blocking as far as the main thread of execution is concerned.
If the blocking task (or let's call it unit of work) is trivial, we may not be interested in its completion. We are just happy if it executes properly and finishes. But there are cases when we need to know or be notified when the task completes. This is where the idea of callbacks come into the picture, and hence function pointers. Usually the callback method is a something you've written. So when the asynchronous task (or unit of work) completes, you might need something to follow it up. So the follow up tasks are an example of something you'd be writing inside your callback method.
I have been using a lot of C i/o win32 routines. I did come across a routine that allowed you to read a file asynchronously. But I never used it, and hence I never really thought of callbacks as an interesting concept. (It's actually the idea of callbacks that makes us appreciate asynchronous programming). This particular routine is a library routine; it is something developed and packaged as C-libraries for your C programs which are meant only for Windows environments. So it is a routine I can't hack. I don't know how it is implemented underneath. However this routine does allow for the asynchronous pattern of program execution,, and guess what? The last parameter was actually a function pointer that expects a reference to a callback function. Here is a prototype of that:
BOOL WINAPI ReadFileEx(
__in HANDLE hFile,
__out_opt LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__inout LPOVERLAPPED lpOverlapped,
__in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
So I hope you now understand that delegates are the only things close to function pointers in the .NET programming framework. And they are mainly there if you want to employ a callback pattern in your solution. Since a delegate is a type, and it is an instance of the
System.Delegate class, we have a lot of extra features added to it. You can actually assign a method that is synchronous to it, and then invoke it to execute in an asynchronous fashion. Now if you ask me what is the difference between a delegate and a function pointer, I'd say with a delegate you can invoke synchronous methods asynchronously whereas, function pointers are not meant to do such a thing!
- Thursday, Jan 1st 2009: I've written about this again here.
- Wednesday, Jan 7th 2009: You can also perform chain invocation with delegates. Here your delegate can point to more than one function, and they are invoked in the order in which they were referred.