|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionIn this article, I've covered a brief introduction about delegates. This can be a good 'Beginner's Guide' to delegates. BackgroundHere, 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 DelegateA 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 ' '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 ' typedef void (*GreetingDelegate) (char *); This delegate is only capable of calling a method that takes a 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 '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 '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 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 DelegatesComing to multicast delegates, these are delegates which are capable of pointing to multiple functions of the same signature. The To demonstrate a multicast delegate, I've added a new function ' 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 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 Console.WriteLine("Adding 'MorningGreets' And" & _
" 'EveningGreets' References To A Delegate...")
Dim AllGreets As GreetingDelegate = _
[Delegate].Combine(MorningGreets, EveningGreets)
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 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 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.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||