Freigeben über


Delegaten (Visual Basic)

Delegaten sind Objekte, die auf Methoden verweisen. Sie werden manchmal als typsichere Funktionszeiger beschrieben, da sie mit Funktionszeigern vergleichbar sind, die in anderen Programmiersprachen verwendet werden. Im Gegensatz zu Funktionszeigern sind Visual Basic-Stellvertretungen jedoch ein Verweistyp, der auf der Klasse System.Delegatebasiert. Stellvertretungen können auf beide freigegebenen Methoden verweisen – Methoden, die ohne eine bestimmte Instanz einer Klasse aufgerufen werden können – und auf Instanzmethoden.

Stellvertretungen und Ereignisse

Delegaten sind in Situationen hilfreich, in denen Sie einen Mittler zwischen einer aufrufenden Prozedur und der aufgerufenen Prozedur benötigen. Sie können z. B. ein Objekt verwenden, das Ereignisse auslöst, um unterschiedliche Ereignishandler unter unterschiedlichen Umständen aufrufen zu können. Leider kann das Objekt, das die Ereignisse auslöst, nicht vorab wissen, welcher Ereignishandler ein bestimmtes Ereignis behandelt. Mit Visual Basic können Sie Ereignishandler dynamisch Ereignissen zuordnen, indem Sie einen Delegaten für Sie erstellen, wenn Sie die AddHandler Anweisung verwenden. Zur Laufzeit leitet der Delegat dann Aufrufe an den entsprechenden Ereignishandler weiter.

Obwohl Sie eigene Stellvertretungen erstellen können, erstellt Visual Basic in den meisten Fällen den Delegat und kümmert sich um die Details für Sie. 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 wird die explizite Erstellung einer Instanz von EventHandler, mit einem Verweis auf die Methode Button1_Click , die als Argument gesendet wird, angezeigt. Die zweite Zeile ist eine bequemere Möglichkeit, dasselbe zu tun.

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

Sie können die Kurzform des Erstellens von Delegaten an einer beliebigen Stelle verwenden, an der der Compiler den Typ des Delegaten 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, wie:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

Dies ist nützlich, wenn Sie mehrere Ereignisse an denselben Handler weiterleiten möchten.

Delegatvariablen und -parameter

Sie können Stellvertretungen für andere, nicht ereignisbezogene Aufgaben verwenden, wie zum Beispiel freies Threaden oder Verfahren, die zur Laufzeit verschiedene Funktionsversionen aufrufen müssen.

Angenommen, Sie haben eine Kleinanzeigen-Anwendung, die ein Listenfeld mit den Namen von Autos enthält. Die Anzeigen werden nach Titel sortiert, was in der Regel die Marke des Autos ist. Ein Problem kann auftreten, wenn bei einigen Autos das Baujahr vor der Marke angegeben ist. Das Problem besteht darin, dass die integrierte Sortierfunktion des Listenfelds nur nach Zeichencodes sortiert wird. es platziert alle Anzeigen beginnend mit Datumsangaben zuerst, gefolgt von den Anzeigen, die mit dem Make beginnen.

Um dies zu beheben, können Sie eine Sortierprozedur in einer Klasse erstellen, die die standardmäßige alphabetische Sortierung in den meisten Listenfeldern verwendet, aber zur Laufzeit zur benutzerdefinierten Sortierprozedur für Autoanzeigen wechseln kann. Dazu übergeben Sie die benutzerdefinierte Sortierprozedur während der Laufzeit mithilfe von Delegaten an die Sortierklasse.

AddressOf- und Lambda-Ausdrücke

Jede Delegatklasse definiert einen Konstruktor, der die Spezifikation einer Objektmethode übergeben wird. Ein Argument für einen Delegatkonstruktor muss entweder ein Verweis auf eine Methode oder ein Lambda-Ausdruck sein.

Verwenden Sie die folgende Syntax, um einen Verweis auf eine Methode anzugeben:

AddressOf [expression.]methodName

Der Kompilierungszeittyp des expression Typs muss der Name einer Klasse oder einer Schnittstelle sein, die eine Methode des angegebenen Namens enthält, deren Signatur der Stellvertretungsklasse entspricht. Dies methodName kann eine freigegebene Methode oder eine Instanzmethode sein. Dies methodName ist nicht optional, auch wenn Sie einen Delegaten für die Standardmethode der Klasse erstellen.

Verwenden Sie die folgende Syntax, um einen Lambda-Ausdruck anzugeben:

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 Lambda-Ausdrücken finden Sie unter Lambda-Ausdrücke. Beispiele für Lambda-Ausdrücke und AddressOf-Zuweisungen zu Delegaten finden Sie unter Gelockerte Delegatenkonvertierung.

Titel BESCHREIBUNG
Vorgehensweise: Aufrufen einer Delegate-Methode Stellt ein Beispiel bereit, das zeigt, wie eine Methode einem Delegaten zugeordnet und diese Methode dann über den Delegaten aufgerufen wird.
Vorgehensweise: Übergeben von Prozeduren an eine andere Prozedur in Visual Basic Veranschaulicht, wie Stellvertretungen zum Übergeben einer Prozedur an eine andere Prozedur verwendet werden.
Gelockerte Delegatenkonvertierung Beschreibt, wie Sie Stellvertretungen oder Handlern Unter- und Funktionen zuweisen können, auch wenn ihre Signaturen nicht identisch sind
Ereignisse Bietet eine Übersicht über Ereignisse in Visual Basic.