![]() |
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. |
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: ![]()
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:
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.
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:
|
|
|
||
| Home | Copyright © 2008-2016, FunctionX, Inc. | |
|
|
||