Delegaten (Visual Basic)
Delegaten sind Objekte, die auf Methoden verweisen. Sie werden zuweilen als typsichere Funktionszeiger beschrieben, da sie in anderen Programmiersprachen verwendeten Funktionszeigern ähneln. Im Gegensatz zu Funktionszeigern sind Visual Basic-Delegaten jedoch ein Verweistyp basierend auf der Klasse System.Delegate. Delegaten können sowohl auf freigegebene Methoden – Methoden, die ohne eine bestimmte Instanz einer Klasse aufgerufen werden können – als auch Instanzmethoden verweisen.
Delegaten und Ereignisse
Delegaten sind in Situationen hilfreich, in denen Sie einen Mittler zwischen einer aufrufenden Prozedur und der aufgerufenen Prozedur benötigen. Ein Beispiel: Sie möchten, dass ein Objekt, das Ereignisse auslöst, unter verschiedenen Bedingungen verschiedene Ereignishandler aufrufen kann. Leider ist dem Objekt, das die Ereignisse auslöst, nicht im Voraus bekannt, welcher Ereignishandler ein bestimmtes Ereignis verarbeitet. Visual Basic ermöglicht die dynamische Zuordnung von Ereignishandlern zu Ereignissen, indem ein Delegat für Sie erstellt wird, wenn Sie die AddHandler
-Anweisung verwenden. Zur Laufzeit leitet der Delegat dann Aufrufe an den entsprechenden Ereignishandler weiter.
Sie können zwar auch eigene Delegaten erstellen, doch in den meisten Fällen generiert Visual Basic den Delegaten und verarbeitet die Details. Eine Event
-Anweisung definiert z.B. implizit eine Delegatklasse mit dem Namen <EventName>EventHandler
als geschachtelte Klasse der Klasse, die die Event
-Anweisung enthält, und mit der gleichen Signatur wie das Ereignis. Die AddressOf
-Anweisung erstellt implizit eine Instanz eines Delegaten, die auf eine bestimmte Prozedur verweist. Die folgenden beiden Codezeilen sind gleichwertig. In der ersten Zeile sehen Sie die explizite Erstellung einer Instanz von EventHandler
mit einem Verweis auf die Button1_Click
-Methode, die als Argument gesendet wird. Die zweite Zeile ist eine praktischere Möglichkeit, das Gleiche auszuführen.
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
Die schnelle Methode zum Erstellen von Delegaten können Sie immer dort verwenden, wo der Compiler den Delegattyp anhand des Kontexts bestimmen kann.
Deklarieren von Ereignissen, die einen vorhandenen Delegattyp verwenden
In manchen Situationen empfiehlt es sich, ein Ereignis so zu deklarieren, dass es einen vorhandenen Delegattyp als zugrunde liegenden Delegaten verwendet. Die folgende Syntax veranschaulicht dies:
Delegate Sub DelegateType()
Event AnEvent As DelegateType
Dies ist nützlich, wenn mehrere Ereignisse an den gleichen Handler weitergeleitet werden sollen.
Delegatvariablen und -parameter
Sie können Delegaten für andere, nicht auf Ereignisse bezogene Tasks (z.B. freies Threading) oder für Prozeduren verwenden, die zur Laufzeit verschiedene Versionen von Funktionen aufrufen müssen.
Ein Beispiel: Eine Anwendung für Gebrauchtwagen-Kleinanzeigen enthält ein Listenfeld mit den Namen von Fahrzeugen. Die Anzeigen sind nach Titel sortiert, wobei es sich in der Regel um die Marke handelt. Ein Problem kann dann auftreten, wenn bei einigen Autos das Baujahr vor der Marke steht. Das Problem besteht darin, dass die integrierte Suchfunktion des Listenfelds nur nach Zeichencodes sortiert. Daher werden alle Anzeigen, die mit dem Jahr beginnen, an den Beginn der Liste sortiert, erst dann folgen die Anzeigen, die mit der Marke beginnen.
Um dies zu beheben, können Sie eine Sortierprozedur in einer Klasse erstellen, die in den meisten Listenfeldern die standardmäßige alphabetische Sortierung verwendet, jedoch zur Laufzeit auf die benutzerdefinierte Sortierung für Gebrauchtwagenanzeigen umgestellt werden kann. Dafür übergeben Sie die benutzerdefinierte Sortierprozedur mithilfe von Delegaten zur Laufzeit an die Sortierklasse.
AddressOf- und Lambda-Ausdrücke
Jede Delegatklasse definiert einen Konstruktor, dem die Spezifikation einer Objektmethode übergeben wird. Ein Argument für einen Delegatkonstruktor muss ein Verweis auf eine Methode oder ein Lambda-Ausdruck sein.
Verwenden Sie die folgende Syntax, um einen Verweis auf eine Methode festzulegen:
AddressOf
[expression
.]methodName
Der Typ von expression
muss zur Kompilierungszeit der Name einer Klasse oder Schnittstelle sein, die eine Methode des angegebenen Namens enthält, deren Signatur mit der Signatur der Delegatklasse übereinstimmt. Bei methodName
kann es sich um eine freigegebene Methode oder um eine Instanzmethode handeln. Der methodName
ist nicht optional, selbst dann nicht, wenn Sie einen Delegaten für die Standardmethode der Klasse erstellen.
Verwenden Sie die folgende Syntax, um einen Lambda-Ausdruck festzulegen:
Function
([parm
As type
, parm2
As type2
, ...]) expression
Das folgende Beispiel zeigt sowohl AddressOf
- als auch Lambda-Ausdrücke, mit denen der Verweis für einen Delegaten angegeben wird.
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
Console.WriteLine(_num1 & " " & _num2)
Else
Console.WriteLine(_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
Die Signatur der Funktion muss mit der des Delegattyps übereinstimmen. Weitere Informationen zu Lambdaausdrücken finden Sie unter Lambda Expressions (Lambdaausdrücke). Beispiele für Lambda-Ausdrücke und AddressOf
-Zuweisungen zu Delegaten finden Sie unter Gelockerte Delegatenkonvertierung.
Verwandte Themen
Titel | Beschreibung |
---|---|
Vorgehensweise: Aufrufen einer Delegatenmethode | Zeigt anhand eines Beispiels, wie Sie eine Methode einem Delegaten zuweisen und diese Methode anschließend über den Delegaten aufrufen. |
Gewusst wie: Übergeben von Prozeduren an eine andere Prozedur in Visual Basic | Veranschaulicht, wie Delegaten verwendet werden, um eine Prozedur an eine andere Prozedur zu übergeben. |
Gelockerte Delegatenkonvertierung | Beschreibt, wie Subs und Funktionen Delegaten oder Handlern zugewiesen werden können, auch wenn deren Signaturen nicht identisch sind. |
Ereignisse | Stellt eine Übersicht über Ereignisse in Visual Basic bereit. |