Gelockerte Delegatenkonvertierung
Aktualisiert: November 2007
Die in Visual Basic 2008 eingeführte gelockerte Delegatenkonvertierung ermöglicht das Zuweisen von Unterroutinen und Funktionen zu Delegaten oder Handlern, auch wenn deren Signaturen nicht identisch sind. Das Binden an Delegaten ist deshalb konsistent mit dem bereits zulässigen Binden für Methodenaufrufe.
Parameter und Rückgabetyp
Anstatt der exakten Übereinstimmung von Signaturen setzt die gelockerte Konvertierung voraus, dass die folgenden Bedingungen erfüllt sind, wenn Option Strict auf On festgelegt ist:
Eine Erweiterungskonvertierung aus dem Datentyp der einzelnen Delegatparameter in den Datentyp des entsprechenden Parameters der zugewiesenen Funktion oder Sub muss vorhanden sein. Im folgenden Beispiel verfügt der Delegat Del1 über einen Parameter, eine Integer. Der Parameter m in den zugewiesenen Lambda-Ausdrücken muss über einen Datentyp verfügen, für den eine Erweiterungskonvertierung aus Integer, z. B. Long oder Double, unterstützt wird.
' 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
Einschränkende Konvertierungen sind nur erlaubt, wenn Option Strict auf Off festgelegt ist.
' 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
Eine Erweiterungskonvertierung in die entgegengesetzte Richtung aus dem Rückgabetyp der zugewiesenen Funktion oder Sub in den Rückgabetyp des Delegaten muss vorhanden sein. In den folgenden Beispielen muss der Text jedes zugewiesenen Lambda-Ausdrucks als Datentyp ausgewertet werden, der zu Integer erweitert wird, da der Rückgabetyp von del1Integer ist.
' 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)
Wenn Option Strict auf Off festgelegt ist, wird die Erweiterungseinschränkung in beiden Richtungen entfernt.
' 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)
Auslassen von Parameterspezifikationen
Bei Verwendung gelockerter Delegaten können Sie Parameterspezifikationen in der zugewiesenen Methode vollständig auslassen:
' 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))
Beachten Sie, dass Sie nicht einige Parameter angeben und andere weglassen dürfen.
' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p
Dies ist in Situationen wie dem Definieren eines Ereignishandlers hilfreich, in denen mehrere komplexe Parameter berücksichtigt werden müssen. Die Argumente für einige Ereignishandler werden nicht verwendet. Stattdessen greift der Handler direkt auf den Zustand des Steuerelements zu, für das das Ereignis registriert wurde, und ignoriert die Argumente. Mithilfe von gelockerten Delegaten können Sie die Argumente in Deklarationen weglassen, in denen keine Mehrdeutigkeiten auftreten. Im folgenden Beispiel kann die vollständig angegebene Methode OnClick als RelaxedOnClick umgeschrieben werden.
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-Beispiele
Lambda-Ausdrücke werden in den vorherigen Beispielen verwendet, um die Typbeziehungen leicht erkennbar zu machen. Die gleichen Lockerungen sind jedoch für Delegatzuweisungen zulässig, die AddressOf, Handles oder AddHandler verwenden.
Im folgenden Beispiel können die Funktionen f1, f2, f3 und f4 alle Del1 zugewiesen werden.
' 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
Das folgende Beispiel ist nur gültig, wenn Option Strict auf Off festgelegt ist.
' 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))
Ignorieren von Funktionsrückgabewerten
Über die gelockerte Delegatenkonvertierung können Sie einem Sub-Delegaten eine Funktion zuweisen und so den Rückgabewert der Funktion vollständig ignorieren. Sie können einem Funktionsdelegaten jedoch kein Sub zuweisen. Im folgenden Beispiel wird die Adresse von Funktion doubler dem Sub-Delegaten Del3 zugewiesen.
' 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))
Siehe auch
Aufgaben
Gewusst wie: Übergeben von Prozeduren an eine andere Prozedur in Visual Basic
Gewusst wie: Schreiben von Ereignishandlern
Konzepte
Erweiternde und eingrenzende Konvertierungen
Delegaten und der AddressOf-Operator
WithEvents und die Handles-Klausel