Home

Delegates

 

Introduction

The C and C++ concept of function pointer was very useful when programming for the Microsoft Windows operating systems because the Win32 library relies on the concept of callback functions to process messages. For this reason and because of their functionality, callback functions were carried out in the .NET Framework but they were defined with the name of delegate.

A delegate is a special type of user-defined variable that is declared globally, like a class. In fact, a delegate is created like an interface but appearing as a method. Based on this, a delegate provides a template for a method, like an interface provides a template for a class. Like an interface, a delegate is not defined. Its role is to show what a useful method would look like. To support this concept, a delegate can provide all the necessary information that would be used on a method. This includes a return type, either no argument or one or more arguments.

     

Declaring a Delegate

To declare a delegate, you use the delegate keyword. The basic formula used to create a delegate is:

[modifier] Delegate Name (parameter(s)) As ReturnType

The modifier factor can be Public, Private, or Friend.

The Delegate keyword is required.

The Name must be a valid name for a procedure.

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.

The ReturnType can be any of the data types we have used so far.

Here is an example of creating a delegate:

Imports System.Windows.Forms

Module Exercise

    Delegate Sub Simple()

    Public Class Starter
        Inherits Form

        Dim components As System.ComponentModel.Container

        Public Sub New()

        End Sub

        Public Sub InitializeComponent()
            
        End Sub

    End Class

End Module

After declaring a delegate, remember that it only provides a template for a procedure, not an actual function. Before using it, you must define a procedure that would carry an assignment the procedure is supposed to perform. That procedure must have the same return type and the same (number of) argument(s), if any. Here is an example:

Imports System.Windows.Forms

Module Exercise

    Delegate Sub Simple()

    Public Class Starter
        Inherits Form

        Dim components As System.ComponentModel.Container

        Public Sub New()

        End Sub

        Public Sub InitializeComponent()
            
        End Sub

    End Class

    Private Sub Welcome()

    End Sub

End Module

After implementing the procedure, you can associate it to the name of the delegate. To do that, where you want to use the procedure, declare a variable of the type of the delegate using the New operator. In the parentheses of the constructor, access the name of the procedure by its address, using the AddressOf operator. Here is an example that uses a delegate:

Imports System.Windows.Forms

Module Exercise

    Delegate Sub Simple()

    Public Class Starter
        Inherits Form

        Dim components As System.ComponentModel.Container

        Public Sub New()

        End Sub

        Public Sub InitializeComponent()
            
            Dim Announce As Simple = New Simple(AddressOf Welcome)

        End Sub

    End Class

    Private Sub Welcome()

    End Sub

    Function Main() As Integer

        Dim frmStart As Starter

        frmStart = New Starter
        Application.Run(frmStart)

        Return 0
    End Function

End Module

You can also declare a delegate that returns a value. When defining a function that would be associated with the delegate, remember that that function must return the same type of value. Here is an example:

Imports System.Drawing
Imports System.Windows.Forms

Module Exercise

    Private txtOperation As TextBox
    Delegate Function Addition() As Double

    Public Class Starter
        Inherits Form

        Dim components As System.ComponentModel.Container

        Public Sub New()
            InitializeComponent()
        End Sub

        Public Sub InitializeComponent()
            Dim add As Addition = New Addition(AddressOf Plus)

            txtOperation = New TextBox
            txtOperation.Location = New Point(100, 20)
            Controls.Add(txtOperation)

            txtOperation.Text = CStr(add())
        End Sub

    End Class

    Private Function Plus() As Double

            Dim a As Double = 248.66, b As Double = 50.28
            Plus = a + b

    End Function

    Function Main() As Integer

        Dim frmStart As Starter = New Starter

        Application.Run(frmStart)

        Return 0
    End Function

End Module

This would produce:

Delegate

Delegates and Classes

In the above introductions, we associated delegates with general procedures. Because delegates are usually declared globally, that is outside of a class, they can be associated with almost any function of the application, provided the function has the same return type and the same (number of) argument(s), if any, as the delegate. When you create a procedure that would be associated with a delegate, you can also define it as Shared.

Different functions can be associated to delegates. Here is an example of two functions associated with a common delegate:

Imports System.Drawing
Imports System.Windows.Forms

Module Exercise

    Delegate Function Multiplication() As Double

    Public Class Cube
        Private _side As Double

        Public Property Side() As Double
            Get
                Return _side
            End Get
            Set(ByVal value As Double)
                _side = value
            End Set
        End Property

        Public Sub New()
            _side = 0
        End Sub

        Public Sub New(ByVal s As Double)
            _side = s
        End Sub

        Public Function Area() As Double
            Return 6 * _side * _side
        End Function

        Public Function Volume() As Double
            Return _side * _side * _side
        End Function
    End Class

    Public Class Starter
        Inherits Form

        Private lblSide As Label
        Private txtSide As TextBox
        Private lblArea As Label
        Private txtArea As TextBox
        Private lblVolume As Label
        Private txtVolume As TextBox

        Dim components As System.ComponentModel.Container

        Public Sub New()
            InitializeComponent()
        End Sub

        Public Sub InitializeComponent()
            Dim SmallBox As Cube = New Cube(25.58)

            Text = "Cube Calculation"

            lblSide = New Label
            lblSide.Location = New Point(21, 19)
            lblSide.Text = "Side:"
            lblSide.AutoSize = True

            txtSide = New TextBox
            txtSide.Location = New Point(87, 16)

            lblArea = New Label
            lblArea.Location = New Point(21, 47)
            lblArea.Text = "Area:"
            lblArea.AutoSize = True

            txtArea = New TextBox
            txtArea.Location = New Point(87, 44)

            lblVolume = New Label
            lblVolume.Location = New Point(21, 75)
            lblVolume.Text = "Volume:"
            lblVolume.AutoSize = True

            txtVolume = New TextBox
            txtVolume.Location = New Point(87, 72)

            Controls.Add(lblSide)
            Controls.Add(txtSide)
            Controls.Add(lblArea)
            Controls.Add(txtArea)
            Controls.Add(lblVolume)
            Controls.Add(txtVolume)

            Dim AreaDefinition As Multiplication = _
		New Multiplication(AddressOf SmallBox.Area)
            Dim VolDefinition As Multiplication = _
		New Multiplication(AddressOf SmallBox.Volume)

            txtSide.Text = CStr(SmallBox.Side)
            txtArea.Text = CStr(SmallBox.Area)
            txtVolume.Text = CStr(SmallBox.Volume)
        End Sub

    End Class

    Function Main() As Integer

        Dim frmStart As Starter = New Starter

        Application.Run(frmStart)

        Return 0
    End Function

End Module

This would produce:

Delegate

A Delegate That Takes One of More Arguments

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:

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

    Public Class Starter
        Inherits Form

        Dim components As System.ComponentModel.Container

        Public Sub New()
            InitializeComponent()
        End Sub

        Public Sub InitializeComponent()

            Dim AreaDefinition As Multiplication = _
		New Multiplication(AddressOf Area)
            
        End Sub

    End Class

End Module

When accessing the delegate, call the Invoke() method that the delegates inherit from their parent the Delegate class. 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

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

    Public Class Starter
        Inherits Form

        Private lblSide As Label
        Private txtSide As TextBox
        Private lblArea As Label
        Private txtArea As TextBox
        Private lblVolume As Label
        Private txtVolume As TextBox

        Dim components As System.ComponentModel.Container

        Public Sub New()
            InitializeComponent()
        End Sub

        Public Sub InitializeComponent()
            Dim _side As Double = 46.95

            Text = "Cube Calculation"

            lblSide = New Label
            lblSide.Location = New Point(21, 19)
            lblSide.Text = "Side:"
            lblSide.AutoSize = True

            txtSide = New TextBox
            txtSide.Location = New Point(87, 16)

            lblArea = New Label
            lblArea.Location = New Point(21, 47)
            lblArea.Text = "Area:"
            lblArea.AutoSize = True

            txtArea = New TextBox
            txtArea.Location = New Point(87, 44)

            lblVolume = New Label
            lblVolume.Location = New Point(21, 75)
            lblVolume.Text = "Volume:"
            lblVolume.AutoSize = True

            txtVolume = New TextBox
            txtVolume.Location = New Point(87, 72)

            Controls.Add(lblSide)
            Controls.Add(txtSide)
            Controls.Add(lblArea)
            Controls.Add(txtArea)
            Controls.Add(lblVolume)
            Controls.Add(txtVolume)

            Dim AreaDefinition As Multiplication = _
		New Multiplication(AddressOf Area)
            Dim VolDefinition As Multiplication = _
		New Multiplication(AddressOf Volume)

            txtSide.Text = CStr(_side)
            txtArea.Text = CStr(AreaDefinition.Invoke(_side))
            txtVolume.Text = CStr(VolDefinition.Invoke(_side))
        End Sub

    End Class

    Function Main() As Integer

        Dim frmStart As Starter = New Starter

        Application.Run(frmStart)

        Return 0
    End Function

End Module

Notice that only the name of the method is passed to the delegate. To actually use the delegate, when calling it, in its parentheses, provide a value for the argument(s) conform to the type specified when declaring the delegate.

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

    Public Class Circle
        Private _radius As Double

        Public Property Radius() As Double
            Get
                Return _radius
            End Get
            Set(ByVal value As Double)
                _radius = value
            End Set
        End Property
    End Class

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 argument, the argument(s) must be provided in the parentheses of the called delegate. Here is an example:

Imports System.Drawing
Imports System.Windows.Forms

Module Exercise

    Delegate Function Squared(ByVal value As Double) As Double

    Public Class Circle
        Private _radius As Double

        Public Property Radius() As Double
            Get
                Return _radius
            End Get
            Set(ByVal value As Double)
                _radius = value
            End Set
        End Property

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

End Module

After declaring a delegate, remember to define a procedure that implements the needed behavior of that delegate. Here is an example:

Imports System.Drawing
Imports System.Windows.Forms

Module Exercise

    Delegate Function Squared(ByVal value As Double) As Double

    Public Class Circle
        Private _radius As Double

        Public Property Radius() As Double
            Get
                Return _radius
            End Get
            Set(ByVal value As Double)
                _radius = value
            End Set
        End Property

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

    Public Class Exercise
        Inherits Form

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

End Module

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:

Imports System.Drawing
Imports System.Windows.Forms

Module Exercise

    Delegate Function Squared(ByVal value As Double) As Double

    Public Class Circle
        Private _radius As Double

        Public Property Radius() As Double
            Get
                Return _radius
            End Get
            Set(ByVal value As Double)
                _radius = value
            End Set
        End Property

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

    Public Class Starter
        Inherits Form

        Private lblSide As Label
        Private txtSide As TextBox
        Private lblArea As Label
        Private txtArea As TextBox

        Dim components As System.ComponentModel.Container

        Public Sub New()
            InitializeComponent()
        End Sub

        Public Sub InitializeComponent()
            Dim _side As Double = 46.95

            Text = "Circle Calculation"

            lblSide = New Label
            lblSide.Location = New Point(21, 19)
            lblSide.Text = "Side:"
            lblSide.AutoSize = True

            txtSide = New TextBox
            txtSide.Location = New Point(87, 16)

            lblArea = New Label
            lblArea.Location = New Point(21, 47)
            lblArea.Text = "Area:"
            lblArea.AutoSize = True

            txtArea = New TextBox
            txtArea.Location = New Point(87, 44)

            Controls.Add(lblSide)
            Controls.Add(txtSide)
            Controls.Add(lblArea)
            Controls.Add(txtArea)

            Dim AreaDefinition As Squared = New Squared(AddressOf ValueTimesValue)

            txtSide.Text = CStr(_side)
            txtArea.Text = CStr(AreaDefinition.Invoke(_side))
        End Sub

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

    Function Main() As Integer

        Dim frmStart As Starter = New Starter

        Application.Run(frmStart)

        Return 0
    End Function

End Module

This would produce:

Delegate

 

Home Copyright © 2008-2016, FunctionX, Inc.