Sideway
output.to from Sideway
Draft for Information Only

Content

VB.NET Delegates
 Delegates and Events
 Declaring Events that Use an Existing Delegate Type
 Delegate Variables and Parameters
 AddressOf and Lambda Expressions
 Related Topics
  How to: Invoke a Delegate Method
  Create the delegate and matching procedures
 See also
  How to: Pass Procedures to Another Procedure in Visual Basic
  Create the delegate and matching procedures
 See also
  Relaxed Delegate Conversion
 Parameters and Return Type
 Omitting Parameter Specifications
 AddressOf Examples
 Dropping Function Returns
 See also
  Source/Reference

VB.NET Delegates

Delegates are objects that refer to methods. They are sometimes described as type-safe function pointers because they are similar to function pointers used in other programming languages. But unlike function pointers, Visual Basic delegates are a reference type based on the class System.Delegate. Delegates can reference both shared methods — methods that can be called without a specific instance of a class — and instance methods.

Delegates and Events

Delegates are useful in situations where you need an intermediary between a calling procedure and the procedure being called. For example, you might want an object that raises events to be able to call different event handlers under different circumstances. Unfortunately, the object raising the events cannot know ahead of time which event handler is handling a specific event. Visual Basic lets you dynamically associate event handlers with events by creating a delegate for you when you use the AddHandler statement. At run time, the delegate forwards calls to the appropriate event handler.

Although you can create your own delegates, in most cases Visual Basic creates the delegate and takes care of the details for you. For example, an Event statement implicitly defines a delegate class named <EventName>EventHandler as a nested class of the class containing the Event statement, and with the same signature as the event. The AddressOf statement implicitly creates an instance of a delegate that refers to a specific procedure. The following two lines of code are equivalent. In the first line, you see the explicit creation of an instance of EventHandler, with a reference to method Button1_Click sent as the argument. The second line is a more convenient way to do the same thing.

VB
AddHandler Button1.Click, New EventHandler(AddressOf Button1_Click)
' The following line of code is shorthand for the previous line.
AddHandler Button1.Click, AddressOf Me.Button1_Click

You can use the shorthand way of creating delegates anywhere the compiler can determine the delegate's type by the context.

Declaring Events that Use an Existing Delegate Type

In some situations, you may want to declare an event to use an existing delegate type as its underlying delegate. The following syntax demonstrates how:

VB
Delegate Sub DelegateType()
Event AnEvent As DelegateType

This is useful when you want to route multiple events to the same handler.

Delegate Variables and Parameters

You can use delegates for other, non-event related tasks, such as free threading or with procedures that need to call different versions of functions at run time.

For example, suppose you have a classified-ad application that includes a list box with the names of cars. The ads are sorted by title, which is normally the make of the car. A problem you may face occurs when some cars include the year of the car before the make. The problem is that the built-in sort functionality of the list box sorts only by character codes; it places all the ads starting with dates first, followed by the ads starting with the make.

To fix this, you can create a sort procedure in a class that uses the standard alphabetic sort on most list boxes, but is able to switch at run time to the custom sort procedure for car ads. To do this, you pass the custom sort procedure to the sort class at run time, using delegates.

AddressOf and Lambda Expressions

Each delegate class defines a constructor that is passed the specification of an object method. An argument to a delegate constructor must be a reference to a method, or a lambda expression.

To specify a reference to a method, use the following syntax:

AddressOf [expression.]methodName

The compile-time type of the expression must be the name of a class or an interface that contains a method of the specified name whose signature matches the signature of the delegate class. The methodName can be either a shared method or an instance method. The methodName is not optional, even if you create a delegate for the default method of the class.

To specify a lambda expression, use the following syntax:

Function ([parm As type, parm2 As type2, ...]) expression

The following example shows both AddressOf and lambda expressions used to specify the reference for a delegate.

VB
Module Module1

    Sub Main()
        ' Create an instance of InOrderClass and assign values to the properties.
        ' InOrderClass method ShowInOrder displays the numbers in ascending 
        ' or descending order, depending on the comparison method you specify.
        Dim inOrder As New InOrderClass
        inOrder.Num1 = 5
        inOrder.Num2 = 4

        ' Use AddressOf to send a reference to the comparison function you want
        ' to use.
        inOrder.ShowInOrder(AddressOf GreaterThan)
        inOrder.ShowInOrder(AddressOf LessThan)

        ' Use lambda expressions to do the same thing.
        inOrder.ShowInOrder(Function(m, n) m > n)
        inOrder.ShowInOrder(Function(m, n) m < n)
    End Sub

    Function GreaterThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
        Return num1 > num2
    End Function

    Function LessThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
        Return num1 < num2
    End Function

    Class InOrderClass
        ' Define the delegate function for the comparisons.
        Delegate Function CompareNumbers(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
        ' Display properties in ascending or descending order.
        Sub ShowInOrder(ByVal compare As CompareNumbers)
            If compare(_num1, _num2) Then
                ${a}(_num1 & "  " & _num2)
            Else
                ${a}(_num2 & "  " & _num1)
            End If
        End Sub

        Private _num1 As Integer
        Property Num1() As Integer
            Get
                Return _num1
            End Get
            Set(ByVal value As Integer)
                _num1 = value
            End Set
        End Property

        Private _num2 As Integer
        Property Num2() As Integer
            Get
                Return _num2
            End Get
            Set(ByVal value As Integer)
                _num2 = value
            End Set
        End Property
    End Class
End Module

The signature of the function must match that of the delegate type. For more information about lambda expressions, see Lambda Expressions. For more examples of lambda expression and AddressOf assignments to delegates, see Relaxed Delegate Conversion.

Related Topics

Title Description
How to: Invoke a Delegate Method Provides an example that shows how to associate a method with a delegate and then invoke that method through the delegate.
How to: Pass Procedures to Another Procedure in Visual Basic Demonstrates how to use delegates to pass one procedure to another procedure.
Relaxed Delegate Conversion Describes how you can assign subs and functions to delegates or handlers even when their signatures are not identical
Events Provides an overview of events in Visual Basic.

How to: Invoke a Delegate Method

This example shows how to associate a method with a delegate and then invoke that method through the delegate.

Create the delegate and matching procedures

  1. Create a delegate named MySubDelegate.

    VB
    Delegate Sub MySubDelegate(ByVal x As Integer)
    
  2. Declare a class that contains a method with the same signature as the delegate.

    VB
    Class class1
        Sub Sub1(ByVal x As Integer)
            MsgBox("The value of x is: " & CStr(x))
        End Sub
    End Class
    
  3. Define a method that creates an instance of the delegate and invokes the method associated with the delegate by calling the built-in Invoke method.

    VB
    Protected Sub DelegateTest()
        Dim c1 As New class1
        ' Create an instance of the delegate.
        Dim msd As MySubDelegate = AddressOf c1.Sub1
        ' Call the method.
        msd.Invoke(10)
    End Sub
    

See also

How to: Pass Procedures to Another Procedure in Visual Basic

This example shows how to use delegates to pass a procedure to another procedure.

A delegate is a type that you can use like any other type in Visual Basic. The AddressOf operator returns a delegate object when applied to a procedure name.

This example has a procedure with a delegate parameter that can take a reference to another procedure, obtained with the AddressOf operator.

Create the delegate and matching procedures

  1. Create a delegate named MathOperator.

    VB
    Delegate Function MathOperator( 
        ByVal x As Double, 
        ByVal y As Double 
    ) As Double
    
  2. Create a procedure named AddNumbers with parameters and return value that match those of MathOperator, so that the signatures match.

    VB
    Function AddNumbers( 
        ByVal x As Double, 
        ByVal y As Double 
    ) As Double
        Return x + y
    End Function
    
  3. Create a procedure named SubtractNumbers with a signature that matches MathOperator.

    VB
    Function SubtractNumbers( 
        ByVal x As Double, 
        ByVal y As Double
    ) As Double
        Return x - y
    End Function
    
  4. Create a procedure named DelegateTest that takes a delegate as a parameter.

    This procedure can accept a reference to AddNumbers or SubtractNumbers, because their signatures match the MathOperator signature.

    VB
    Sub DelegateTest( 
        ByVal x As Double, 
        ByVal op As MathOperator, 
        ByVal y As Double 
    )
        Dim ret As Double
        ret = op.Invoke(x, y) ' Call the method.
        MsgBox(ret)
    End Sub
    
  5. Create a procedure named Test that calls DelegateTest once with the delegate for AddNumbers as a parameter, and again with the delegate for SubtractNumbers as a parameter.

    VB
    Protected Sub Test()
        DelegateTest(5, AddressOf AddNumbers, 3)
        DelegateTest(9, AddressOf SubtractNumbers, 3)
    End Sub
    

    When Test is called, it first displays the result of AddNumbers acting on 5 and 3, which is 8. Then the result of SubtractNumbers acting on 9 and 3 is displayed, which is 6.

See also

Relaxed Delegate Conversion

Relaxed delegate conversion enables you to assign subs and functions to delegates or handlers even when their signatures are not identical. Therefore, binding to delegates becomes consistent with the binding already allowed for method invocations.

Parameters and Return Type

In place of exact signature match, relaxed conversion requires that the following conditions be met when Option Strict is set to On:

  • A widening conversion must exist from the data type of each delegate parameter to the data type of the corresponding parameter of the assigned function or Sub. In the following example, the delegate Del1 has one parameter, an Integer. Parameter m in the assigned lambda expressions must have a data type for which there is a widening conversion from Integer, such as Long or Double.

    VB
    ' Definition of delegate Del1.
    Delegate Function Del1(ByVal arg As Integer) As Integer
    
    VB
    ' Valid lambda expression assignments with Option Strict on or off:
    
    ' Integer matches Integer.
    Dim d1 As Del1 = Function(m As Integer) 3
    
    ' Integer widens to Long
    Dim d2 As Del1 = Function(m As Long) 3
    
    ' Integer widens to Double
    Dim d3 As Del1 = Function(m As Double) 3
    

    Narrowing conversions are permitted only when Option Strict is set to Off.

    VB
    ' Valid only when Option Strict is off:
    
    Dim d4 As Del1 = Function(m As String) CInt(m)
    Dim d5 As Del1 = Function(m As Short) m
    
  • A widening conversion must exist in the opposite direction from the return type of the assigned function or Sub to the return type of the delegate. In the following examples, the body of each assigned lambda expression must evaluate to a data type that widens to Integer because the return type of del1 is Integer.

    VB
    ' Valid return types with Option Strict on:
    
    ' Integer matches Integer.
    Dim d6 As Del1 = Function(m As Integer) m
    
    ' Short widens to Integer.
    Dim d7 As Del1 = Function(m As Long) CShort(m)
    
    ' Byte widens to Integer.
    Dim d8 As Del1 = Function(m As Double) CByte(m)
    

If Option Strict is set to Off, the widening restriction is removed in both directions.

VB
' Valid only when Option Strict is set to Off.

' Integer does not widen to Short in the parameter.
Dim d9 As Del1 = Function(n As Short) n

' Long does not widen to Integer in the return type.
Dim d10 As Del1 = Function(n As Integer) CLng(n)

Omitting Parameter Specifications

Relaxed delegates also allow you to completely omit parameter specifications in the assigned method:

VB
' Definition of delegate Del2, which has two parameters.
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer
VB
' The assigned lambda expression specifies no parameters, even though
' Del2 has two parameters. Because the assigned function in this 
' example is a lambda expression, Option Strict can be on or off.
' Compare the declaration of d16, where a standard function is assigned.
Dim d11 As Del2 = Function() 3

' The parameters are still there, however, as defined in the delegate.
${a}(d11(5, "five"))

' Not valid.
' ${a}(d11())
' ${a}(d11(5))

Note that you cannot specify some parameters and omit others.

VB
' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p

The ability to omit parameters is helpful in a situation such as defining an event handler, where several complex parameters are involved. The arguments to some event handlers are not used. Instead, the handler directly accesses the state of the control on which the event is registered, and ignores the arguments. Relaxed delegates allow you to omit the arguments in such declarations when no ambiguities result. In the following example, the fully specified method OnClick can be rewritten as RelaxedOnClick.

VB
Sub OnClick(ByVal sender As Object, ByVal e As EventArgs) Handles b.Click  
    MessageBox.Show("Hello World from" + b.Text)  
End Sub  
  
Sub RelaxedOnClick() Handles b.Click  
    MessageBox.Show("Hello World from" + b.Text)  
End Sub  

AddressOf Examples

Lambda expressions are used in the previous examples to make the type relationships easy to see. However, the same relaxations are permitted for delegate assignments that use AddressOf, Handles, or AddHandler.

In the following example, functions f1, f2, f3, and f4 can all be assigned to Del1.

VB
' Definition of delegate Del1.
Delegate Function Del1(ByVal arg As Integer) As Integer
VB
' Definitions of f1, f2, f3, and f4.
Function f1(ByVal m As Integer) As Integer
End Function

Function f2(ByVal m As Long) As Integer
End Function

Function f3(ByVal m As Integer) As Short
End Function

Function f4() As Integer
End Function
VB
' Assignments to function delegate Del1.

' Valid AddressOf assignments with Option Strict on or off:

' Integer parameters of delegate and function match.
Dim d13 As Del1 = AddressOf f1

' Integer delegate parameter widens to Long.
Dim d14 As Del1 = AddressOf f2

' Short return in f3 widens to Integer.
Dim d15 As Del1 = AddressOf f3

The following example is valid only when Option Strict is set to Off.

VB
' If Option Strict is Off, parameter specifications for f4 can be omitted.
Dim d16 As Del1 = AddressOf f4

' Function d16 still requires a single argument, however, as specified
' by Del1.
${a}(d16(5))

' Not valid.
'${a}(d16())
'${a}(d16(5, 3))

Dropping Function Returns

Relaxed delegate conversion enables you to assign a function to a Sub delegate, effectively ignoring the return value of the function. However, you cannot assign a Sub to a function delegate. In the following example, the address of function doubler is assigned to Sub delegate Del3.

VB
' Definition of Sub delegate Del3.
Delegate Sub Del3(ByVal arg1 As Integer)

' Definition of function doubler, which both displays and returns the
' value of its integer parameter.
Function doubler(ByVal p As Integer) As Integer
    Dim times2 = 2 * p
    ${a}("Value of p: " & p)
    ${a}("Double p:   " & times2)
    Return times2
End Function
VB
' You can assign the function to the Sub delegate:
Dim d17 As Del3 = AddressOf doubler

' You can then call d17 like a regular Sub procedure.
d17(5)

' You cannot call d17 as a function. It is a Sub, and has no 
' return value.
' Not valid.
'${a}(d17(5))

See also

Source/Reference


©sideway

ID: 200900030 Last Updated: 9/30/2020 Revision: 0 Ref:

close

References

  1. Active Server Pages,  , http://msdn.microsoft.com/en-us/library/aa286483.aspx
  2. ASP Overview,  , http://msdn.microsoft.com/en-us/library/ms524929%28v=vs.90%29.aspx
  3. ASP Best Practices,  , http://technet.microsoft.com/en-us/library/cc939157.aspx
  4. ASP Built-in Objects,  , http://msdn.microsoft.com/en-us/library/ie/ms524716(v=vs.90).aspx
  5. Response Object,  , http://msdn.microsoft.com/en-us/library/ms525405(v=vs.90).aspx
  6. Request Object,  , http://msdn.microsoft.com/en-us/library/ms524948(v=vs.90).aspx
  7. Server Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525541(v=vs.90).aspx
  8. Application Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525360(v=vs.90).aspx
  9. Session Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms524319(8v=vs.90).aspx
  10. ASPError Object,  , http://msdn.microsoft.com/en-us/library/ms524942(v=vs.90).aspx
  11. ObjectContext Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525667(v=vs.90).aspx
  12. Debugging Global.asa Files,  , http://msdn.microsoft.com/en-us/library/aa291249(v=vs.71).aspx
  13. How to: Debug Global.asa files,  , http://msdn.microsoft.com/en-us/library/ms241868(v=vs.80).aspx
  14. Calling COM Components from ASP Pages,  , http://msdn.microsoft.com/en-us/library/ms524620(v=VS.90).aspx
  15. IIS ASP Scripting Reference,  , http://msdn.microsoft.com/en-us/library/ms524664(v=vs.90).aspx
  16. ASP Keywords,  , http://msdn.microsoft.com/en-us/library/ms524672(v=vs.90).aspx
  17. Creating Simple ASP Pages,  , http://msdn.microsoft.com/en-us/library/ms524741(v=vs.90).aspx
  18. Including Files in ASP Applications,  , http://msdn.microsoft.com/en-us/library/ms524876(v=vs.90).aspx
  19. ASP Overview,  , http://msdn.microsoft.com/en-us/library/ms524929(v=vs.90).aspx
  20. FileSystemObject Object,  , http://msdn.microsoft.com/en-us/library/z9ty6h50(v=vs.84).aspx
  21. http://msdn.microsoft.com/en-us/library/windows/desktop/ms675944(v=vs.85).aspx,  , ADO Object Model
  22. ADO Fundamentals,  , http://msdn.microsoft.com/en-us/library/windows/desktop/ms680928(v=vs.85).aspx
close

Latest Updated LinksValid XHTML 1.0 Transitional Valid CSS!Nu Html Checker Firefox53 Chromena IExplorerna
IMAGE

Home 5

Business

Management

HBR 3

Information

Recreation

Hobbies 8

Culture

Chinese 1097

English 339

Reference 79

Computer

Hardware 249

Software

Application 213

Digitization 32

Latex 52

Manim 205

KB 1

Numeric 19

Programming

Web 289

Unicode 504

HTML 66

CSS 65

SVG 46

ASP.NET 270

OS 429

DeskTop 7

Python 72

Knowledge

Mathematics

Formulas 8

Algebra 84

Number Theory 206

Trigonometry 31

Geometry 34

Coordinate Geometry 2

Calculus 67

Complex Analysis 21

Engineering

Tables 8

Mechanical

Mechanics 1

Rigid Bodies

Statics 92

Dynamics 37

Fluid 5

Fluid Kinematics 5

Control

Process Control 1

Acoustics 19

FiniteElement 2

Natural Sciences

Matter 1

Electric 27

Biology 1

Geography 1


Copyright © 2000-2024 Sideway . All rights reserved Disclaimers last modified on 06 September 2019