Was ist ein Delegat bzw. wie ruft man Methoden wann auf?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Was ist ein Delegat bzw. wie ruft man Methoden wann auf?

    Hallo,

    die folgende Problematik habe ich immer wenn es um Threading geht, da es dort häufiger auftaucht anscheinend. Problematik im Sinne vom Verständnis; zum Laufen kriege ich es schon, aber ich weiß nie warum sozusagen.
    Mal anhand des Beispiels eines Threading.TimerCallbacks:

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim callBack As TimerCallback = New TimerCallback(AddressOf Test)
    3. End Sub
    4. Private Sub Test()
    5. '
    6. End Sub

    Warum klappt das?

    oder aber das:

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim callBack As TimerCallback = New TimerCallback(Sub() Test)
    3. End Sub
    4. Private Sub Test()
    5. '
    6. End Sub

    Gibt es dazwischen schon einen Unterschied?

    Und warum klappt das nicht?

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim callBack As TimerCallback = New TimerCallback(Test())
    3. End Sub
    4. Private Sub Test()
    5. '
    6. End Sub


    Viele Grüße
    @Haudruferzappeltnoch Ein Delegat ist im Prinzip die Deklaration für die Signatur einer Prozedur.
    Mit Hilfe von Delegaten kannst Du beliebige Prozedeuren gleicher Signatur an wen auch immer übergeben.
    Für den Empfänger ist in diesem Kontext allein wichtig, dass die übergebenen Parameter stimmen.
    Bei Deinem Code fehlt diese Deklaration von TimerCallback, ich nehme mal dies an:

    VB.NET-Quellcode

    1. Delegate Sub TimerCallback()
    Bei deinem letzten Beispiel stimmt die Implementierung nicht mit der Deklaration überein.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich denke TimerCallback ist eine Klasse. Und der Konstruktor nimmt eine Methode entgegen bzw. ein Delegat wahrscheinlich.

    Aber den Unterschied zwischen Delegat und Methode verstehe ich immer noch nicht

    Wenn ich an eine Methode einen Wert übergeben ist doch egal ob der in einer Variablen steckt oder nicht
    Dim f = 2 : EineMethode(f) = EineMethode(2)
    @Haudruferzappeltnoch Sieh Dir mal dieses Beispiel an:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. ' Deklaration des Delegaten
    3. Delegate Function MyDelegate() As String
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. ' Aufruf mehrerer Funktionen als Delegat
    6. DoAny(AddressOf Del1)
    7. DoAny(AddressOf Del2)
    8. DoAny(AddressOf Del3)
    9. DoAny(AddressOf Del4)
    10. End Sub
    11. ' Prozedur, die einen Delegaten als Parameter erwartet
    12. Private Sub DoAny(Del As MyDelegate)
    13. MessageBox.Show(Del())
    14. End Sub
    15. Private Function Del1() As String
    16. Return "1"
    17. End Function
    18. Private Function Del2() As String
    19. Return "2"
    20. End Function
    21. Private Function Del3() As String
    22. Return "3"
    23. End Function
    24. Private Function Del4() As String
    25. Return "4"
    26. End Function
    27. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Haudruferzappeltnoch schrieb:

    Ich denke TimerCallback ist eine Klasse.
    Zunächstmal:
    Lies dir Buch. Den Löffelmann. Da sind solche Dinge vernünftig, richtig, und im Zusammenhang erklärt.

    Ansonsten:
    TimerCallback ist ein Datentyp.
    Es gibt fünf Arten von Datentypen: Class, Structure, Interface, Enum, Delegate
    Die Liste ist damit vollständig - merk sie dir.
    Meist sagt man "Klasse", wenn man Datentyp meint, und meist ist das sogar richtig. Und in den anderen Fällen ja auch nicht ganz falsch.

    Haudruferzappeltnoch schrieb:

    Und der Konstruktor nimmt eine Methode entgegen bzw. ein Delegat wahrscheinlich.
    Hihi - Sowas kommt bei raus, wenn man Begriffe nicht nachliest: Da "denkt" man dann, und am Ende entstehen "wahrscheinliche" Delegaten - happy coding! :)
    Und insgesamt auch nicht ganz verkehrt. Aber richtig richtig eben auch nicht.
    Richtig ist:
    TimerCallback ist ein Delegat. Und der Konstruktor nimmt einen MethodenZeiger entgegen, gekennzeichnet durch das Schlüsselwort Addressof.



    Zu deiner Eingangsfrage:
    Einen Delegat-Objekt kannste dir als Variable vorstellen, die auf eine Methode zeigt. Wichtig dabei ist, dass die Signatur des Delegaten mit der Signatur der Methode übereinstimmt (Wie das so ist in einer typisierten Programmiersprache: Datentypen müssen zusammenpassen).
    in Alles über Events verbreiter ich mich auch über Delegaten, weil die bei Events eine ebenso fundamentale Rolle spielen wie beim Threading - guck dir das mal an.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ah, das verändert schonmal einiges, ich dachte die Methode Test() wäre der Delegat. Ich schau mir deine Events mal in einer ruhigen Minute an.

    Ist denn ein Unterschied zwischen den Argumenten hier EinDelegat(AddressOf Test) und EinDelegat(Sub() Test)?

    Also angenommen Test wäre eine Function also Test() as Irgendwas. Dann würde ich mit EinDelegat(Test()) natürlich Irgendwas statt der Function selbst übergeben.
    Wenn eine Function als Argument Irgendwas ist, was ist dann eine Methode als Argument? Einfach Nothing weil es keine Rückgabe gibt?

    Also ich weiß ein Integer ist eigentlich ein Wertetyp, aber wenn man es mal der Einfachheit halber genauso betrachtet wie die meisten anderen Objekte:
    Dann hätte ich bei Dim var as Integer = 2 eine 2 im Speicher mit dem Zeiger var
    Analog ist AddressOf Test der Zeiger zu Test(), aber ist Test() ein Objekt im Speicher?

    Haudruferzappeltnoch schrieb:

    Ist denn ein Unterschied zwischen den Argumenten hier EinDelegat(AddressOf Test) und EinDelegat(Sub() Test)?
    Probiere es aus.
    Lies in den Docs nach und erfreue uns mit Deiner Erkenntnis.
    Irgendwann musst Du mal anfangen, selbst die erforderlichen Informationen zu akquirieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Naja dass beides funktioniert habe ich ja schon geschrieben. Also nach eurer Kenntnis gibt es keinen Unterschied, willst du mir damit wahrscheinlich sagen.
    Sowas kann man in den Docs leider nicht in einem gebündelten Zusammenhang finden. Das wirkliche Konzept kann ich einfach nicht über fachlich runtergekochte Definitionen erfassen.
    Dann füge in Deinem Google-Suchstring das Wort "Beispiel" hinzu.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Haudruferzappeltnoch schrieb:

    Ist denn ein Unterschied zwischen den Argumenten hier EinDelegat(AddressOf Test) und EinDelegat(Sub() Test)?
    Probiere es aus.
    Naja - das führt wohl leicht zum falschen Schluss, dass da kein Unterschied sei.

    Daher mein Vorschlag: Guck hin - ist da ein Unterschied?
    Ich tät vermeinen ja:
    AddressOf Test ist die Addresse einer Methode.
    Sub() Test()ist eine (anonyme) Methode, die eine andere Methode aufruft.
    Jo, letztendlich bei rauskommen tut das gleiche: ein Delegat, der Test() aufruft - mal direkt, mal weniger direkt.
    Wirklich sehen wird man den Unterschied wohl im Disassembler.