Home

Delegates

 

Delegates Fundamentals

 

Introduction

As done when you declare a variable, when you create and call a procedure, it uses a section of memory of the computer. This section is its address. You can access that area of memory to get to the procedure. Or, you can declare a variable that would be used to access the memory used by the procedure.

A function pointer is a special type of variable that is used to access a function using its address. To support function pointers, the .NET Framework provides the concept of delegates. A delegate is not a real function. It provides a syntax for a function that it would be associated with.

Creating a Delegate

Before using a delegate, you must create it or you can use one of the built-in delegates of the .NET Framework. The basic formula to create a delegate is:

[modifier] Delegate Sub/Function Name (parameter(s)) As ReturnType

The modifier factor can be Public, Private, or Friend. This is followed by either the Delegate Sub or the Delegate Function expression.

A delegate must have a name: The Name factor of this formula. The name follows the rules we have been observing for valid names of the Visual Basic language.

Because a delegate is some type of a template for a procedure, you must use parentheses. If this procedure will not take any argument, you can leave the parentheses empty.

If the delegate will be associated with a sub-procedure, there is no return type. Here is an example:

Module Exercise

    Delegate Sub Messenger()

End Module

If the delegate is a function-type, you must specify a ReturnType. This can be any of the data types we have used so far, or it can be a class.

If you create a procedure that would be associated with a delegate, you can also define it as Shared.

Associating a Delegate to a Procedure

Before using a delegate, you must create a procedure it will be associated with. The procedure must use the same syntax as the delegate:

  • If using a sub-procedure, both must be created as sub-procedures
  • If there is no argument, none of them can take an argument

Here is an example:

Module Exercise
    Delegate Sub Messenger()

    Private Sub ShowMessage()
        MsgBox("Main message")
    End Sub

End Module

Getting the Address of a Procedure

To associate a procedure to a delegate, you must assign the address of the procedure to a variable of the delegate. This means that you must first declare a variable for the delegate.

To assist you with getting the address of a procedure, the Visual Basic language provides the AddressOf operator. To use it, type it followed by the name of the procedure that implements the delegate. Assign that expression to the variable declared from the delegate. Here is an example:

Module Exercise
    Delegate Sub Messenger()

    Private Sub ShowMessage()
        MsgBox("Main message")
    End Sub

    Public Function Main() As Integer
        Dim Mess As Messenger

        Mess = AddressOf ShowMessage

        Return 0
    End Function

End Module

After assigning the address of the procedure to the delegate's variable, you can call the delegate as if it were a procedure. Here is an example:

Module Exercise
    Delegate Sub Messenger()

    Private Sub ShowMessage()
        MsgBox("Main message")
    End Sub

    Public Function Main() As Integer
        Dim Mess As Messenger

        Mess = AddressOf ShowMessage
        Mess()

        Return 0
    End Function

End Module

In our example, we used a sub-procedure. In the same way, if necessary, you can create a delegate as a function. In this case, you would define a function to associate to that delegate. Then, you can use the same techniques we followed to associate them.

Delegates and Classes

When it comes to delegates, not only can you use a normal procedure, you can use the method of a class to associate to a delegate. You can start by creating the class and the necessary method. Here is an example:

Module Exercise

    Private Class Example
        Public Sub Welcome()
            MsgBox("A delegate with class")
        End Sub
    End Class

End Module

Of course, before using the delegate, you must declare it. This is done exactly as previously. The delegate must be of the same type as the method (sub-procedure or function).

Before associating the delegate to the intended method, declare a variable for it. Also declare a variable for the class. To associate the method to the delegate, get the address of the method, through its object, and assign it to the variable of the delegate. Once you have done this, you can call the delegate's variable as if it were a procedure. Here is an example:

Module Exercise

    Delegate Sub Simple()

    Private Class Example
        Public Sub Welcome()
            MsgBox("A delegate with class")
        End Sub
    End Class

    Public Function Main() As Integer
        Dim Simplicity As Simple
        Dim Exo As Example = New Example

        Simplicity = AddressOf Exo.Welcome
        Simplicity()

        Return 0
    End Function

End Module

A delegate is actually a class. The class is named Delegate. Based on this, whenever you create a delegate, the name you give it is considered an object. That is, the name you give to the delegate becomes an object of type Delegate. Based on the characteristics of classes, that delegate object automatically becomes equipped with methods.

 

 

 

 

Delegates and Arguments

 

Introduction

If you want to associate a procedure that takes arguments to a delegate, when declaring the delegate, provide the necessary argument(s) in its parentheses. Here is an example of a delegate that takes two arguments (and returns a value):

Module Exercise

    Delegate Function Multiplication(ByVal value As Double) As Double

End Module

When defining the associated procedure, besides returning the same type of value, make sure that the procedure takes the same number of arguments. Here is an example:

Imports System.Drawing
Imports System.Windows.Forms

Module Exercise

    Delegate Function Multiplication(ByVal value As Double) As Double

    Public Function Area(ByVal Side As Double) As Double
        Return 6 * Side * Side
    End Function

End Module

To associate the procedure, declare a variable of the type of delegate and access the name of the procedure using the AddressOf operator. Here is an example:

Module Exercise
    Delegate Function Multiplication(ByVal value As Double) As Double

    Public Function Area(ByVal Side As Double) As Double
        Return 6 * Side * Side
    End Function

    Public Function Main() As Integer

        Dim AreaDefinition As Multiplication = New Multiplication(AddressOf Area)

        Return 0
    End Function

End Module

To assist you with accessing a delegate, the Delegate class is equipped with a method named Invoke. Therefore, to associate a method to a delegate, call this method on the variable of the delegate. The syntax of the Invoke() method is:

Public Function Invoke(method As Delegate) As Object

Here is an example:

Module Exercise
    Delegate Function Multiplication(ByVal value As Double) As Double

    Public Function Area(ByVal Side As Double) As Double
        Return 6 * Side * Side
    End Function

    Public Function Volume(ByVal Side As Double) As Double
        Return Side * Side * Side
    End Function

    Public Function Main() As Integer

        Dim Side As Double = 46.95
        Dim AreaDefinition As Multiplication
        Dim VolDefinition As Multiplication

        AreaDefinition = New Multiplication(AddressOf Area)
        VolDefinition = New Multiplication(AddressOf Volume)

        MsgBox("Cube Calculation" & vbCrLf & _
               "Side: " & vbTab & CStr(Side) & vbCrLf & _
               "Area: " & vbTab & CStr(AreaDefinition.Invoke(Side)) & vbCrLf & _
               "Volume: " & vbTab & CStr(VolDefinition.Invoke(Side)))

        Return 0
    End Function

End Module

A Delegate Passed as Argument

Using delegates, a procedure can be indirectly passed as argument to another procedure. To proceed, first declare the necessary delegate. Here is a example of such a delegate:

Module Exercise

    Delegate Function Squared(ByVal value As Double) As Double

End Module

A delegate can be passed as argument to a procedure. Such an argument would be used as if it were a procedure itself. This means that, when accessed in the body of the procedure, the name of the delegate must be accompanied by parentheses and if the delegate takes an argument or arguments, the argument(s) must be provided in the parentheses of the called delegate. Here is an example:

Module Exercise
    Private Radius As Double
    Delegate Function Squared(ByVal value As Double) As Double

    Public Function Area(ByVal sqd As Squared) As Double
        Return sqd(Radius) * Math.PI
    End Function
End Module

After declaring a delegate, remember to define a procedure that implements the needed behavior of that delegate. Once the procedure is ready, to associate it to a delegate, declare a variable of the type of the delegate using the New operator. In the parentheses of the constructor, access the name of the associated procedure using the AddressOf operator. To access the delegate, call the Invoke() method. Here is an example:

Module Exercise
    Private Radius As Double
    Delegate Function Squared(ByVal value As Double) As Double

    Public Function Area(ByVal sqd As Squared) As Double
        Return sqd(Radius) * Math.PI
    End Function

    Public Function ValueTimesValue(ByVal value As Double) As Double
        Return value * value
    End Function

    Public Function Main() As Integer

        Dim Side As Double = 46.95
        Dim AreaDefinition As Squared

        AreaDefinition = New Squared(AddressOf ValueTimesValue)

        MsgBox("Circle Calculation" & vbCrLf & _
               "Side: " & vbTab & CStr(Side) & vbCrLf & _
               "Area: " & vbTab & CStr(AreaDefinition.Invoke(Side)))

        Return 0
    End Function

End Module
 
 
   
 

Home Copyright © 2009-2010 FunctionX, Inc.