Avslappnad delegatkonvertering (Visual Basic)

Med avslappnad delegatkonvertering kan du tilldela subs och funktioner till ombud eller hanterare även när deras signaturer inte är identiska. Därför blir bindningen till ombud konsekvent med bindningen som redan tillåts för metodanrop.

Parametrar och returtyp

I stället för exakt signaturmatchning kräver avslappnad konvertering att följande villkor uppfylls när Option Strict är inställt på On:

  • En utvidgad konvertering måste finnas från datatypen för varje delegatparameter till datatypen för motsvarande parameter för den tilldelade funktionen eller Sub. I följande exempel har ombudet Del1 en parameter, en Integer. Parametern m i de tilldelade lambda-uttrycken måste ha en datatyp för vilken det finns en bredare konvertering från Integer, till exempel Long eller Double.

    ' Definition of delegate Del1.
    Delegate Function Del1(ByVal arg As Integer) As Integer
    
    ' 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
    

    Begränsade konverteringar tillåts endast när Option Strict är inställt på Off.

    ' 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
    
  • En utvidgad konvertering måste finnas i motsatt riktning från returtypen för den tilldelade funktionen eller Sub till ombudets returtyp. I följande exempel måste brödtexten för varje tilldelat lambda-uttryck utvärderas till en datatyp som vidgas till Integer eftersom returtypen del1 är Integer.

    ' 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)
    

Om Option Strict är inställt på Offtas breddningsbegränsningen bort i båda riktningarna.

' 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)

Utelämna parameterspecifikationer

Med avslappnade ombud kan du också helt utelämna parameterspecifikationer i den tilldelade metoden:

' Definition of delegate Del2, which has two parameters.
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer
' 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.
Console.WriteLine(d11(5, "five"))

' Not valid.
' Console.WriteLine(d11())
' Console.WriteLine(d11(5))

Observera att du inte kan ange vissa parametrar och utelämna andra.

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

Möjligheten att utelämna parametrar är till hjälp i en situation som att definiera en händelsehanterare, där flera komplexa parametrar ingår. Argumenten för vissa händelsehanterare används inte. I stället får hanteraren direkt åtkomst till tillståndet för den kontroll som händelsen är registrerad på och ignorerar argumenten. Med avslappnade ombud kan du utelämna argumenten i sådana deklarationer när inga tvetydigheter uppstår. I följande exempel kan den fullständigt angivna metoden OnClick skrivas om som RelaxedOnClick.

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-exempel

Lambda-uttryck används i föregående exempel för att göra typrelationerna enkla att se. Samma avkopplingar tillåts dock för delegerade tilldelningar som använder AddressOf, Handleseller AddHandler.

I följande exempel kan funktioner f1, f2, f3och f4 alla tilldelas till Del1.

' Definition of delegate Del1.
Delegate Function Del1(ByVal arg As Integer) As Integer
' 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
' 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

Följande exempel är endast giltigt när Option Strict är inställt på Off.

' 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.
Console.WriteLine(d16(5))

' Not valid.
'Console.WriteLine(d16())
'Console.WriteLine(d16(5, 3))

Returnerar avsläppningsfunktion

Med avslappnad delegatkonvertering kan du tilldela en funktion till ett Sub ombud, vilket effektivt ignorerar funktionens returvärde. Du kan dock inte tilldela en Sub till ett funktionsdelegat. I följande exempel tilldelas funktionens doubler adress till delegera SubDel3.

' 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
    Console.WriteLine("Value of p: " & p)
    Console.WriteLine("Double p:   " & times2)
    Return times2
End Function
' 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.
'Console.WriteLine(d17(5))

Se även