VB.NET Callback
Inhaltsverzeichnis
VB.NET Callback
Du möchtest mehr darüber lernen, wie Du ein VB.NET Callback verwendest, bzw. was Callbacks sind?
Vielleicht kennst Du Callback–Funktionen 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 – Parent–Methode 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:
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 Callback–Parameters 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 „PassAnonymousInlineAction“ ruft 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 Integer“ welchen 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