Problem bei Konvertierung von C# zu VB.NET: Ereignis als Parameter an Funktion übergeben(?)

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Chris.

    Problem bei Konvertierung von C# zu VB.NET: Ereignis als Parameter an Funktion übergeben(?)

    Hallo liebes Forum,

    ich habe in der Vergangenheit das Forum immer "passiv" konsultiert, wenn ich bei Problemen nicht weiterkam -das hat bisher auch gut funktioniert. Jetzt stehe ich jedoch vor einem Problem welches scheinbar relativ speziell ist -jedenfalls komme ich mit der Suchfunktion alleine nicht weiter.

    Es geht um folgendes: Ich versuche zur Zeit ein C# Projekt zu VB.NET zu übersetzen (es handelt sich um eine API für die Kommunikation mit einen Server) (Link zum Gitthub Projekt: github.com/dougdellolio/coinbasepro-csharp ).
    Mir ist bewusst, dass dies eigentlich nicht nötig ist und ich das C# Projekt direkt in mein Projekt importieren könnte.
    Da ich C# jedoch nicht beherrsche wollte ich das Projekt in VB.NET übersetzen, um nachvollziehen zu können wie der Code funktioniert (er soll unter anderem als Übung dienen, um Eventhandling zu lernen, da ich mich damit noch nicht viel beschäftigt habe (bei vb.net läuft das interessante ja hinter dem Vorhang ab, natürlich ist mir bewusst, dass MouseClicks etc. alles Events sind und ich Events daher schon immer verwendet habe, aber eben nicht selbst gestrickt habe).

    Bei dem voeliegenden Probelem habe ich versucht die Zeilen per Converter in VB.NET zu übersetzen (was natürlich nicht funktioniert hat). Dann kam ich auf die Idee das Projekt in eine DLL zu kompilieren und danach wieder in vb.net zu decompilieren, da ich dachte durch die CIL wären C# und vb.net leicht ineinander überführbar. Leider gibt der Decompiler auch hier auf. Es scheint also eine Grundfunktionalität bei C# zu geben (Übergabe eines Ereignisses als Parameter an eine Funktion bzw. einen Eventhandler an eine Prozedur anhängen -wobei ich eher glaube, das ich gar nicht richtig verstanden habe was in diesen Zeilen passiert ?( ), welches bei vb.net nicht ohne workaround möglich ist.

    Hier 2 Beispiele wie es im Originalcode von C# aussieht:

    C#-Quellcode

    1. public void WebSocket_Closed(object sender, EventArgs e)
    2. {
    3. webSocketFeed.Invoke(OnWebSocketClose, sender, new WebfeedEventArgs<EventArgs>(e));
    4. webSocketFeed.Dispose();
    5. if (!stopWebSocket)
    6. {
    7. Start(productTypes, channelTypes);
    8. }
    9. }


    C#-Quellcode

    1. public void Start(
    2. List<ProductType> productTypes,
    3. List<ChannelType> channelTypes = null)
    4. {
    5. if (productTypes.Count == 0)
    6. {
    7. throw new ArgumentException($"You must specify at least one {nameof(productTypes)}");
    8. }
    9. stopWebSocket = false;
    10. this.productTypes = productTypes;
    11. this.channelTypes = channelTypes;
    12. webSocketFeed = createWebSocketFeed();
    13. webSocketFeed.Closed += WebSocket_Closed;
    14. webSocketFeed.Error += WebSocket_Error;
    15. webSocketFeed.MessageReceived += WebSocket_MessageReceived;
    16. webSocketFeed.Opened += WebSocket_Opened;
    17. webSocketFeed.Open();
    18. Log.Information("WebSocket started with {@ProductTypes} {@ChannelTypes}", this.productTypes, this.channelTypes);
    19. }


    Die Zeilen 3 bzw. 16 bis 21 wären die, die ich nicht verstehe.

    Es wäre super, wenn mir jemand erläutern könnte warum das bei vb.net anders gemacht werden muss und vor allem, was hier überhaupt passiert.

    Wenn weitere Informationen nötig sind, meldet Euch einfach, dann füge ich sie noch hinzu.


    Vielen Dank im Voraus!
    Willkommen im Forum. :thumbup:

    Chris schrieb:

    Übergabe eines Ereignisses als Parameter an eine Funktion bzw. einen Eventhandler an eine Prozedur anhängen
    Unterschiedlich ist hier, wie Eventhandler-Prozeduren in VB.NET und C# zugewiesen werden.
    In C# hast Du es vorliegen.
    In VB würde das so aussehen:

    VB.NET-Quellcode

    1. AddHandler webSocketFeed.Closed, AddressOf WebSocket_Closed
    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!
    Vielen Dank für die schnelle Antwort und das Willkommen! ^^

    Sowas ähnliches hatte ich mich von dem "Alles über Events" Tut von ErfinderDesRades bereits auch abgeleitet:

    VB.NET-Quellcode

    1. AddHandler webSocketFeed.Closed, New EventHandler(AddressOf WebSocket_Closed)


    Allerdings verstehe ich leider nicht, wie das auf das 1. Beispiel mit der Invoke Prozedur anzuwenden ist und schon gar nicht, warum der Decompiler das nicht gebacken kriegt ?(

    Chris schrieb:

    warum der Decompiler das nicht gebacken kriegt
    So ein armes Schwein von Decompiler ist eben auch nur ein Mensch.
    Da funktioniert eben auch nicht alles korrekt, und was syntaktisch in C# geht, geht noch lange nicht in VB.NET und umgekehrt :!:
    Da musst Du Dir alles ansehen und das was nicht compiliert, verstehen(!!!) und korrigieren.
    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!

    Chris schrieb:

    Allerdings verstehe ich leider nicht, wie das auf das 1. Beispiel mit der Invoke Prozedur anzuwenden ist
    gar nicht.
    Dort musste anderes in Anschlag bringen.
    Nämlich OnWebSocketClose ist höchstwahrscheinlich eine Methoden-Addresse (ist in c# nur im Kontext eindeutig erkennbar).
    Methoden-Addressen formuliert man in vb so: AddressOf OnWebSocketClose.
    Das ist ja leider grade das was ich nicht verstehe:
    OnWebSocketClose ist als Event deklariert:

    C#-Quellcode

    1. public event EventHandler<WebfeedEventArgs<EventArgs>> OnWebSocketClose;


    WebSocketFeed.Invoke ist eine Prozedur:

    C#-Quellcode

    1. void Invoke<T>(
    2. EventHandler<WebfeedEventArgs<T>> onReceived,
    3. object sender,
    4. WebfeedEventArgs<T> webfeedEventArgs);


    VB.NET-Quellcode

    1. webSocketFeed.Invoke(OnWebSocketClose, sender, New WebfeedEventArgs(Of EventArgs)(e))

    funktioniert nicht, weil ein Ereignis nicht direkt aufgerufen werden kann und man es mit RaiseEvent machen sollte.

    Aber soweit ich es verstanden habe, soll der Eventhandler an die Prozedur übergeben werden?

    Ich dachte man müsste über sowas wie Delegaten gehen. -Aber ich glaube eher ich habe hier einen grundlegenden Denkfehler bzw. etwas grundlegenderes nicht verstanden (wie gesagt beschäftige mich erst seit kurzem mit Events). ;(

    Chris schrieb:

    OnWebSocketClose ist als Event deklariert
    Na, dann ists doch keine Methoden-Addresse, sondern ein Event (was in vb ein Unterschied ist, in c# nicht.)

    Aber guck nochmal die event-deklaration nach, weil das ist das krankeste event, was ich je gesehen hab:

    C#-Quellcode

    1. public event EventHandler<WebfeedEventArgs<EventArgs>> OnWebSocketClose;

    Da könnteste auch in Betracht ziehen, von dieser dll Abstand zu nehmen - mir kommen jdfs. erhebliche Bedenken bezüglich der Code-Qualität, wenn da sowas verzapft ist.

    jdfs. da in vb deutlicher zw event und methodenaddresse unterschieden wird, muss man hier mit RaiseEvent arbeiten. Ausserdem findet ein Invoking statt, das ist in vb insgesamt umständlicher zu formulieren:

    VB.NET-Quellcode

    1. dim dlg as Action(of Object, WebfeedEventArgs(of EventArgs))=sub(s, wfe) raiseevent OnWebSocketClose(s, wfe)
    2. webSocketFeed.Invoke(dlg, sender, new WebfeedEventArgs(of EventArgs)(e))

    keine Ahnung, ob das wirklich funzt, und vmtl. wirds da noch mehr so Scherze geben.
    Ich glaub fast, du solltest die dll - wenn du sie nehmen willst, halt so nehmen wie sie ist - in c#.
    Durch diese Übersetzerei durch mittelbar durch andere scheint mir das Risiko viel zu hoch, dass sich da Fehler einschleichen - die du dann ja auch nicht selbst beheben kannst.
    Sorry für die späte Rückmeldung.

    Um ehrlich zu sein bin ich etwas erleichtert -als ich mir den Code angeschaut habe dachte ich mir nämlich auch sowas wie
    "Gut, ich beschäftige mich noch nicht sooo lange mit Klassen und Events, aber diese extrem verschachtelten Eventhandling-Konstrukte -das kann doch nicht der Sinn der Übung sein!" ?(

    Ich denke ich werde mir ein paar andere Beispiele für die API-Bib anschauen und mir Schritt für Schritt eine eigene basteln -da lernt man eh mehr. Hat bei directx schließlich auch geklappt!

    Danke für die Hilfe und Vorschläge!