Click here to Skip to main content
15,868,016 members
Articles / Programming Languages / Visual Basic
Article

A Beginner's Guide to Delegates

Rate me:
Please Sign up or sign in to vote.
4.65/5 (89 votes)
29 Mar 20064 min read 513.5K   6.9K   177   55
An article on delegates in .NET.

Introduction

In this article, I've covered a brief introduction about delegates. This can be a good 'Beginner's Guide' to delegates.

Background

Here, I assume you have a basic knowledge of function pointers. Because, in the introductory part, I compare delegates with function pointers. For basic ideas on function pointers, please refer this link.

Simple Delegate

A delegate is very much like a C/C++ 'function pointer' or a 'typedef that represents the address of a function'. In C/C++, the address of a function is just a memory address. The C/C++ function pointer holds only the address of a function. This address doesn't carry any additional information, such as the number of parameters expected by the function, types of parameters it takes etc. In fact, this all makes a function pointer type unsafe. Traditionally, calling a function by its address depends on the language supporting the function pointers. And function pointers are inherently dangerous.

Delegates add a safety to the idea of traditional function pointers. The .NET framework has added the bonus of providing a type-safe mechanism called delegates. They follow a Trust-But-Verify model, with automatic verification of the signature by the compiler. Unlike function pointers however, delegates are object-oriented, type-safe, and secured. In short, a delegate is a data structure that refers to a static method or to an object instance, and an instance method of that object. When the delegate references an instance method, it stores not only a reference to the method entry point, but also a reference to the object instance for which to invoke the method.

In VB.NET, we define a delegate using the 'Delegate' keyword. E.g.:

VB
'Defining the delegate 
Public Delegate Sub GreetingDelegate(ByVal MsgString As String)

This does not declare the delegate, it defines it. With this line, we tell the compiler to create a new class called 'GreetingDelegate' that inherits from 'System.Delegate' (the compiler does it automatically for you). This line is equivalent to writing the following code in C/C++:

typedef void (*GreetingDelegate) (char *);

This delegate is only capable of calling a method that takes a String parameter and return nothing. A delegate cares only about the signature of the method you are encapsulating inside of it. So, the function we encapsulate in this delegate (with the appropriate signature) can be invoked safely using this delegate.

Here, I have written two different functions in VB.NET:

VB
Public Sub GoodMoring(ByVal YourName As String)
    Console.WriteLine("Good Morning " + YourName + " !")
End Sub

Public Sub GoodNight(ByVal YourName As String)
    Console.WriteLine("Good Night " + YourName + " !")
End Sub

Now, inside Sub Main, we can create an instance of the delegate, and can assign the address of a function to the delegate. This is done using the AddressOf keyword as follows:

VB
'Instantiating the delegate
Dim MyGreeting As GreetingDelegate

'Here we assign the address of the function we wish to encapsulate
'to the delegate

Console.WriteLine("Adding 'GoodMoring' Reference To A Delegate...")
MyGreeting = AddressOf GoodMoring

Once we assign an address to a delegate, we can use the Invoke method to call the function encapsulated in the delegate.

VB
'Invoking the delegate
Console.WriteLine("Invoking Delegate...")
MyGreeting.Invoke("Mallinath")

Because a delegate cares only about the signature of the method you are encapsulating inside it, we can make it refer to another method also. E.g.:

VB
'Assigning the address of the another function to the same delegate
Console.WriteLine()
Console.WriteLine("Making Existing Delegate To Point To Another Fuction...")
Console.WriteLine("Replacing With Goodnight Reference...")
MyGreeting = New GreetingDelegate(AddressOf Goodnight)

'Another way of invoking the delegate.
Console.WriteLine("Invoking Delegate...")
MyGreeting("Mallinath")

Surprised? Did I forget to put Invoke() there? No! Actually, you don't need to use Invoke(), you can just use the delegate as a proxy for the method.

If you try to assign the address of a method or function not matching the delegate declaration, you'll get a compiler error. Try the following code by putting it in the downloaded source code:

VB
'your existing code goes over here
'add these following lines 
Public Sub BadGreets()
    Console.WriteLine("Wishing You Bad Greetings !")
End Sub

Sub Main()
    'your existing code goes over here
    'add these following lines and try
    MyGreeting = AddressOf BadGreets
    MyGreeting.Invoke("Mallinath")
End Sub

Multicast Delegates

Coming to multicast delegates, these are delegates which are capable of pointing to multiple functions of the same signature. The System.Delegate type maintains a linked list that is used to hold the references to the functions to be invoked by the delegate. This linked list is called as the Invocation List. The delegate class provides a shared member function called Combine(), which adds a reference of specified function to the invocation list.

To demonstrate a multicast delegate, I've added a new function 'GoodEvening', along with the earlier two, to the MulticastDelegate sample program. And I have created separate delegates for each one of the earlier functions.

VB
Public Delegate Sub GreetingDelegate(ByVal MsgString As String)

Public Sub GoodMorning(ByVal YourName As String)
    Console.WriteLine("Good Morning " + YourName + " !")
End Sub

Public Sub Goodnight(ByVal YourName As String)
    Console.WriteLine("Good Night " + YourName + " !")
End Sub

Public Sub GoodEvening(ByVal YourName As String)
    Console.WriteLine("Good Evening " + YourName + " !")
End Sub

In Sub Main, I've instantiated them as:

VB
Dim MorningGreets As GreetingDelegate
Dim EveningGreets As GreetingDelegate

MorningGreets = AddressOf GoodMorning
EveningGreets = New GreetingDelegate(AddressOf GoodEvening)

To illustrate the multicast delegate, I've combined both the delegates into a single delegate, using the Combine() method as:

VB
Console.WriteLine("Adding 'MorningGreets' And" & _
        " 'EveningGreets' References To A Delegate...")
Dim AllGreets As GreetingDelegate = _
        [Delegate].Combine(MorningGreets, EveningGreets)

Combine() returns a new delegate with the merged invocation list of the function references of the specified delegates. Here, we can add one more function reference to the existing delegate as:

VB
Console.WriteLine("Adding Another" & _ 
    " References To Existing Delegate...")
AllGreets = [Delegate].Combine(AllGreets, _
    New GreetingDelegate(AddressOf Goodnight))

As I wrote, the delegate definition line tells the compiler to create a new class inheriting from the System.Delegate type:

VB
Dim NightGreets As GreetingDelegate =  AddressOf Goodnight

This is equivalent to:

VB
Dim NightGreets As GreetingDelegate
NightGreets = New GreetingDelegate(AddressOf Goodnight)

So, the entire thing can be summed up as:

VB
AllGreets = [Delegate].Combine(AllGreets, _
   New GreetingDelegate(AddressOf Goodnight))

As like a function, to add a function reference to a delegate's invocation list, a delegate class provides a function to remove a function reference from the delegate invocation list.

For example:

VB
Console.WriteLine("Removing 'GoodEvening' Reference...")
AllGreets = [Delegate].Remove(AllGreets, EveningGreets)

An Invoke function call on this multicast delegate will call all the functions whose references are stored in the invocation list of that delegate object.

Finally, while concluding multicast delegates, I can say that, it differs from a regular delegate in that it may contain references to more than just one method. Methods in a multicast delegate are executed synchronously when the multicast delegate is invoked, and in the order in which they are added to the list. If one of the called method raises an exception, then the delegate ceases, and the exception is propagated to the delegate caller.

All of the above code used in this article have been put in the samples. You can download and run it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
India India
Hello All !
This is Mallinath S. Karkanti, from India. I'm working as a Software Developer in one of the Middle Scale Company... !

Comments and Discussions

 
GeneralRe: My vote of 2 Pin
Malli_S5-Jul-11 20:55
Malli_S5-Jul-11 20:55 
GeneralMy vote of 5 Pin
Syed Mohsin Ahmed23-May-11 21:14
Syed Mohsin Ahmed23-May-11 21:14 
GeneralMy vote of 5 Pin
Adam Mendoza14-Apr-11 14:02
Adam Mendoza14-Apr-11 14:02 
GeneralMy vote of 5 Pin
tiwal11-Apr-11 3:42
tiwal11-Apr-11 3:42 
GeneralMy vote of 5 Pin
sam viper7-Dec-10 7:13
sam viper7-Dec-10 7:13 
GeneralMy vote of 5 Pin
newlong6-Dec-10 21:53
newlong6-Dec-10 21:53 
Generalgood job......... Pin
santosh d16-Feb-10 20:52
santosh d16-Feb-10 20:52 
GeneralSolid explanation Pin
Daniel Kamisnki5-Feb-09 11:48
Daniel Kamisnki5-Feb-09 11:48 
Great job. Thanks for sharing the knowledge! Smile | :)

Daniel
GeneralOrder of execution Pin
OmegaThree17-Jul-08 10:30
OmegaThree17-Jul-08 10:30 
GeneralExcellent explanation Pin
rlsokoloff3-Oct-07 7:30
rlsokoloff3-Oct-07 7:30 
GeneralGood article in simple terms Pin
nsdlsandy7-Aug-07 5:15
nsdlsandy7-Aug-07 5:15 
GeneralThis is an excellent tutorial. Clear, good examples... Pin
aaava5-Jul-07 15:39
aaava5-Jul-07 15:39 
GeneralA good, clear explanation Pin
authentictech23-Feb-07 4:04
authentictech23-Feb-07 4:04 
GeneralCool article Pin
dbranca6-Apr-06 11:16
dbranca6-Apr-06 11:16 
GeneralExpaination for Beginners Pin
Stewart Badger29-Mar-06 21:55
Stewart Badger29-Mar-06 21:55 
GeneralRe: Expaination for Beginners Pin
Sara_S30-Mar-06 3:19
Sara_S30-Mar-06 3:19 
GeneralRe: Expaination for Beginners Pin
Malli_S31-Mar-06 18:05
Malli_S31-Mar-06 18:05 
GeneralRe: Expaination for Beginners Pin
BPloe4-Apr-06 3:37
BPloe4-Apr-06 3:37 
GeneralRe: Expaination for Beginners Pin
cpayne_stargames19-Apr-06 19:55
cpayne_stargames19-Apr-06 19:55 
GeneralRe: Expaination for Beginners Pin
nzmike23-Apr-06 13:36
nzmike23-Apr-06 13:36 
GeneralRe: Expaination for Beginners Pin
Ken Cash2-Jul-09 8:25
Ken Cash2-Jul-09 8:25 
Answerpossible use Pin
Davide De Conti15-Sep-06 5:17
Davide De Conti15-Sep-06 5:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.