Click here to Skip to main content
Click here to Skip to main content

A Beginner's Guide to Delegates

, 29 Mar 2006
Rate this:
Please Sign up or sign in to vote.
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.:

'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:

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:

'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.

'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.:

'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:

'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.

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:

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:

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:

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:

Dim NightGreets As GreetingDelegate =  AddressOf Goodnight

This is equivalent to:

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

So, the entire thing can be summed up as:

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:

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

Share

About the Author

Malli_S
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

 
SuggestionThank you!!!! PinmemberSahayapraveen4-Jun-12 20:57 
QuestionHelpful PinmemberMember 798693618-May-12 12:01 
QuestionThread Safe Pinmemberbonnsar20-Mar-12 17:32 
AnswerRe: Thread Safe PinmemberMalli_S20-Mar-12 21:18 
GeneralRe: Thread Safe Pinmemberbonnsar20-Mar-12 22:00 
AnswerRe: Thread Safe [modified] PinmemberMalli_S21-Mar-12 2:38 
GeneralRe: Thread Safe Pinmemberbonnsar21-Mar-12 19:08 
GeneralRe: Thread Safe Pinmemberbonnsar25-Mar-12 13:28 
AnswerRe: Thread Safe PinmemberMalli_S26-Mar-12 20:14 
GeneralRe: Thread Safe Pinmemberbonnsar27-Mar-12 20:48 
AnswerRe: Thread Safe Pinmemberbonnsar1-Apr-12 21:30 
AnswerRe: Thread Safe PinmemberMalli_S5-Apr-12 3:44 
GeneralRe: Thread Safe Pinmemberbonnsar6-Apr-12 13:16 
GeneralRe: Thread Safe PinmemberMalli_S9-Apr-12 20:48 
GeneralRe: Thread Safe PinmemberWill Barrows29-Sep-12 7:24 
GeneralRe: Thread Safe Pinmemberbonnsar30-Sep-12 3:43 
GeneralMy vote of 5 Pinmembermanoj kumar choubey5-Mar-12 21:22 
GeneralMy vote of 4 Pinmemberbrief11019-Nov-11 19:04 
GeneralMy vote of 5 PinmemberSaumitra Kumar Paul1-Jun-11 0:17 
GeneralRe: My vote of 5 PinmemberMalli_S5-Jul-11 20:56 
GeneralMy vote of 2 PinmemberKaj Jørgensen29-May-11 10:01 
GeneralRe: My vote of 2 PinmemberMalli_S5-Jul-11 20:55 
GeneralMy vote of 5 Pinmemberamchimum23-May-11 21:14 
GeneralMy vote of 5 PinmemberAdam Mendoza14-Apr-11 14:02 
GeneralMy vote of 5 Pinmembertiwal11-Apr-11 3:42 
GeneralMy vote of 5 Pinmembersam viper7-Dec-10 7:13 
GeneralMy vote of 5 Pinmembernewlong6-Dec-10 21:53 
Generalgood job......... Pinmembersantosh d16-Feb-10 20:52 
GeneralSolid explanation PinmemberDaniel Kamisnki5-Feb-09 11:48 
GeneralOrder of execution PinmemberOmegaThree17-Jul-08 10:30 
GeneralExcellent explanation Pinmemberrlsokoloff3-Oct-07 7:30 
GeneralGood article in simple terms Pinmembernsdlsandy7-Aug-07 5:15 
GeneralThis is an excellent tutorial. Clear, good examples... Pinmemberaaava5-Jul-07 15:39 
GeneralA good, clear explanation PinmemberlooseSparks23-Feb-07 4:04 
GeneralCool article Pinmemberdbranca6-Apr-06 11:16 
GeneralExpaination for Beginners PinmemberStewart Badger29-Mar-06 21:55 
GeneralRe: Expaination for Beginners PinmemberSara_S30-Mar-06 3:19 
GeneralRe: Expaination for Beginners PinmemberMalli_S31-Mar-06 18:05 
GeneralRe: Expaination for Beginners PinmemberBPloe4-Apr-06 3:37 
GeneralRe: Expaination for Beginners Pinmembercpayne_stargames19-Apr-06 19:55 
GeneralRe: Expaination for Beginners Pinmembernzmike23-Apr-06 13:36 
GeneralRe: Expaination for Beginners PinmemberKen Cash2-Jul-09 8:25 
Answerpossible use PinmemberDavide De Conti15-Sep-06 5:17 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140902.1 | Last Updated 29 Mar 2006
Article Copyright 2006 by Malli_S
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid