Volný převod delegáta (Visual Basic)
Uvolněný převod delegáta umožňuje přiřadit podřízené a funkce delegátům nebo obslužným rutinám, i když jejich podpisy nejsou identické. Proto se vazba na delegáty stane konzistentní s vazbou, která je již povolena pro vyvolání metody.
Parametry a návratový typ
Místo přesné shody podpisu vyžaduje uvolnění převodu, aby byly splněny následující podmínky, pokud Option Strict
je nastavena hodnota On
:
Rozšiřující převod musí existovat z datového typu každého parametru delegáta na datový typ odpovídajícího parametru přiřazené funkce nebo
Sub
. V následujícím příkladu má delegátDel1
jeden parametr, anInteger
. Parametrm
v přiřazených výrazech lambda musí mít datový typ, pro který existuje rozšiřující převod zInteger
, napříkladLong
neboDouble
.' 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
Zužující převody jsou povoleny pouze v případech, kdy
Option Strict
je nastavena hodnotaOff
.' 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
Rozšiřující převod musí existovat v opačném směru než návratový typ přiřazené funkce nebo
Sub
návratový typ delegáta. V následujících příkladech musí tělo každého přiřazeného výrazu lambda vyhodnotit na datový typ, který se rozšiřuje,Integer
protože návratovýdel1
typ jeInteger
.' 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)
Pokud Option Strict
je nastavená hodnota Off
, rozšíření omezení se odebere v obou směrech.
' 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)
Vynechání specifikací parametrů
Uvolněné delegáty také umožňují zcela vynechat specifikace parametrů v přiřazené metodě:
' 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))
Všimněte si, že nemůžete zadat některé parametry a vynechat jiné.
' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p
Schopnost vynechat parametry je užitečná v situaci, jako je například definování obslužné rutiny události, kde je zapojeno několik složitých parametrů. Argumenty některých obslužných rutin událostí se nepoužívají. Místo toho obslužná rutina přistupuje přímo ke stavu ovládacího prvku, na kterém je událost zaregistrována, a ignoruje argumenty. Uvolněné delegáty umožňují vynechat argumenty v takových deklaracích, pokud výsledkem nejsou nejednoznačnosti. V následujícím příkladu lze plně zadanou metodu OnClick
přepsat jako 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 Examples
Výrazy lambda se používají v předchozích příkladech k usnadnění zobrazení relací typů. Stejná uvolnění jsou však povolena pro delegovaná přiřazení, která používají AddressOf
, Handles
nebo AddHandler
.
V následujícím příkladu lze funkce f1
, f2
, f3
a f4
všechny být přiřazeny 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
Následující příklad je platný pouze v případě, že Option Strict
je nastavena na 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))
Vrácení funkce vrátí
Uvolněný převod delegáta umožňuje přiřadit funkci delegátu Sub
a efektivně ignorovat návratovou hodnotu funkce. Delegát funkce ale nemůžete přiřadit Sub
. V následujícím příkladu je adresa funkce doubler
přiřazena delegátovi Sub
Del3
.
' 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))