VB.NET Callback

VB.NET Callback
VB.NET Callback

VB.NET Callback

Du möchtest mehr darüber lernen, wie Du ein VB.NET Callback verwendest, bzw. was Callbacks sind?

Vielleicht kennst Du CallbackFunktionen auch schon aus anderen Programmiersprachen, aber auch wenn nicht, kein Problem!

Eventuell hast Du auch noch an folgenden Beiträgen Interesse: VB.NET AndAlso, die AddHandler-Anweisung, oder Application Path.

Was ist ein Callback

Die Frage die sich eventuell zuerst stellt ist, was denn überhaupt ein Callback sein könnte?

Als Callback – auch Rückruffunktion genannt – bezeichnet man eine Methode, Welche einer anderen Methode als Parameter übergeben wird.

Die – ich nenne Sie mal – ParentMethode ruft das Callback dann eventuell mit weiteren Parametern auf und der Code des Callbacks wird somit ausgeführt.

Diese Vorgehensweise kennt man in der Programmierung auch aus dem sogenannten „Inversion of Control„-Prinzip.

Eine Darstellung

Hier möchte ich Dir kurz darstellen, wie ein Callback mehr oder weniger als Pseudo-Code aussehen könnte:

VB.NET Callback Code-Visualisierung
VB.NET Callback Code-Visualisierung

Wie oben beschrieben, wird an einer beliebigen Stelle eine Methode – in diesem Fall die ParentMethod – aufgerufen.

Die ParentMethod bekommt dabei eine weitere Methode (das Callback) als Parameter übergeben.

In der ParentMethod selbst führen wir dann Code in unserer gewünschten Reihenfolge aus und rufen dann das Callback mit eventuellen Parametern auf.

Offene Fragen

Wer schon ein wenig im Bereich Visual Basic .NET unterwegs ist, kennt die normale Struktur von Methoden und eventuellen Parametern schon.

Nun fragt man sich ggf. letztendlich nur, von welchem Datentyp der Callback-Parameter der „ParentMethod“ sein muss.

Dabei spielt natürlich einerseits der Datentyp des Parameters eine Rolle und andererseits die Art der Deklaration.

Gesuchte Datentypen

Für unsere Aufgabe kommen wir nun also zu der finalen Frage, welchen Datentyp wir für die Übergabe des CallbackParameters nutzen können.

Die Antwort lässt sich mit Blick in die .NET-Dokumentation im „System“-Namespace finden und heißt Action„.

Somit können wir den ersten Schritt des Refactorings wagen und unsern Parameter mit einem Datentyp versehen:

    Private Sub ParentMethod(cb As Action)
        ' more..
    End Sub

Nun kommt man an das Problem, dass man erstmal wissen muss, wie man die „ParentMethod“ denn nun aufruft.

VB.NET Callback Action Beispiele

Ein simples Beispiel mit einer Action ohne Parameter könnte wie folgt aussehen:

Private Sub PassAnonymousInlineAction()
    ParentMethod(Sub() Debug.WriteLine(NameOf(PassAnonymousInlineAction)))
End Sub

Private Sub PassAnonymousAction()
    ParentMethod(Sub()
                     Debug.WriteLine($"{NameOf(PassAnonymousAction)} Line 1")
                     Debug.WriteLine($"{NameOf(PassAnonymousAction)} Line 2")
                 End Sub)
End Sub

Private Sub PassKnownAction()
    Dim inlineKnownMethod = Sub() Console.WriteLine("from inline known method")
    ParentMethod(inlineKnownMethod)
    Dim multilineKnownMethod = Sub()
                                   Console.Write("from multiline ")
                                   Console.Write("known method")
                                   Console.WriteLine()
                               End Sub
    ParentMethod(multilineKnownMethod)
End Sub

Anonym einzeilig

Die erste Methode namens „PassAnonymousInlineActionruft die „ParentMethod„-Method mit einer einzeiligen anonymen Action – was „nichts Anderes“ als eine Methode ist – auf.

Anonym mehrzeilig

Bei der zweiten beispielhaften Methode PassAnonymousAction„, übergeben wir der „ParentMethod“ eine mehrzeilige anonyme Methode als Parameter.

Bekannte Methoden

Im letzten Beispiel „PassKnownAction“ rufen wir zwei mal die ParentMethod mit einer bekannten Methode auf.

Mit einfachem Parameter

Nun schauen wir uns an, wie man so einer Action auch einen einfachen Parameter mitliefern kann.

Private Sub ParentMethodInvokingWithSimpleParameter(cb As Action(Of Integer))
    Dim theNumber = 5
    cb(theNumber)
End Sub

Und ein beispielhafter Aufruf:

ParentMethodInvokingWithSimpleParameter(Sub(number) Debug.WriteLine($"You passed a number {number}"))

Mit komplexen Daten

Im nächsten Schritt würde ich gerne ein Beispiel mit komplexeren Daten zeigen.

Dazu brauchen wir im ersten Schritt eine Art Container, Welcher unsere Daten beinhaltet.

Public Class MyArguments

    Public Property FirstName As String

    Public Property LastName As String

    Sub New(firstName As String, lastName As String)
        Me.FirstName = firstName
        Me.LastName = lastName
    End Sub

End Class

Hier wäre die passende Deklaration der Methode:

Private Sub ParentMethodInvokingWithComplexParameter(cb As Action(Of MyArguments))
    Dim args = New MyArguments("John", "Doe")
    cb(args)
End Sub

Und der letztliche Aufruf aus z. B. dem Load-Ereignishandler:

ParentMethodInvokingWithComplexParameter(Sub(args) Debug.WriteLine($"You passed custom args {args}"))

Daten aus VB.NET Callback bekommen

Ich denke der letzte Part, Welcher für Kopfschmerzen sorgen könnte wäre, dass man nun auch Werte aus diesem überlieferten Callback bekommen möchte.

Für gewöhnlich braucht man dafür ja Funktionen, Welche wir hier bisher nicht im Einsatz gesehen haben.

Mache dir aber keine Sorgen, auch dafür gibt es etwas von Ratio.. ich meine einen Datentyp.

Den Datentyp den wir nun im letzten Teil suchen, nennt sich „Func„.

VB.NET Callback Func Beispiele

Um den Rückgabewert eines Callbacks zu erfassen, müssen wir statt der Action-Klasse die Func-Klasse verwenden.

Sehen wir uns dafür einmal dieses Beispiel an:

Private Sub PassingReturnValueOfFunction()
    Dim a = 5
    Dim b = 10
    Dim value = CallbackReturningValue(Function() a * b)
    Debug.WriteLine($"Oh you got a value: {value}")
End Sub

Private Function CallbackReturningValue(cb As Func(Of Integer))
    Dim resultOfCb = cb()
    Return 2 * resultOfCb
End Function

Hier haben wir nun eine Sub, Welche im ersten Step 2 Variablen definiert.

Danach ruft Sie eine Funktion auf, dessen Callback ein Produkt (Mathe, Faktor * Faktor) aufrufende Methode liefert.

Die aufgerufene Funktion darunter nimmt den Rückgabewert des Callbacks (cb) nach dessen Aufruf und multipliziert den Wert nochmal mal 2.

Bei der „CallbackReturningValue„-Funktion definiert das „Of Integerwelchen Rückgabetyp die Funktion hat, also in diesem Fall einen Integer.

Wie verfahre ich nun, wenn ich der „CallbackReturningValue„-Funktion noch einen Parameter mitgeben möchte?

Auch das lässt sich analog zur Action realisieren, indem wir die Func wie folgt definieren:

Private Function CallbackReturningValueWithParam(cb As Func(Of Integer, Integer))
    Dim resultOfCb = cb(5)
    Return resultOfCb
End Function

Der erste Datentyp nach „Func“ definiert bei 2 Parametern, welcher Datentyp als Parameter fungiert.

Danach definiert der 2. Wert bei 2 Parametern, Welchen Rückgabetyp die Funktion hat.

In beiden Fällen verwenden wir hier einen Integer und rufen die Funktion wie folgt durch eine Methode auf:

Private Sub PassingReturnValueOfFunctionWithParam()
    Dim a = 5
    Dim b = 10
    Dim value = CallbackReturningValueWithParam(Function(c) c * a * b)
    Debug.WriteLine($"Oh you got a value with param: {value}")
End Sub

Downloads – VB.NET Callback

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.