Meine EventLogger Class (Feedback usw)

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

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Meine EventLogger Class (Feedback usw)

    Nabend zusammen, :)

    Habe meinen Event/Exception-Logger fertig.
    Nun bitte ich mal um Feedback, was ich ggf anders / besser machen könnte.

    Das LogFile:
    [Info] 10.01.2024 20:26:41
    Mitteilung für den Info_Level

    [Critical] 10.01.2024 20:26:41
    Mitteilung für den Critical-Level

    [Failure] 10.01.2024 20:26:42
    Die arithmetische Operation hat einen Überlauf verursacht.


    Spoiler anzeigen

    Auf dem Main:

    VB.NET-Quellcode

    1. Public Class FrmMain
    2. Private Logger As EventReportLogger ' Deklaration der Logger-Instanz
    3. Public Sub New()
    4. InitializeComponent()
    5. Logger = New EventReportLogger() ' Initialisierung der Logger-Instanz im Konstruktor
    6. End Sub
    7. Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    8. ' Der Level ab wann ins LogFile eingetragen wird
    9. Logger.MinLogLevel = LogLevel.Info
    10. ' Eine einfache Message für Infos
    11. Logger.AddLogEntry(LogLevel.Info, "Mitteilung für den Info_Level")
    12. Logger.AddLogEntry(LogLevel.Critical, "Mitteilung für den Critical-Level")
    13. End Sub
    14. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    15. ' Ein Test für einen Fehler
    16. Try
    17. Dim x As Integer = 1
    18. Dim y As Integer = 0
    19. Dim result As Integer
    20. result = CInt(x / y)
    21. Debug.WriteLine($"Ergebnis: {result}")
    22. Catch ex As Exception
    23. ' Logge die Exception mit verschiedenen Detailoptionen
    24. Logger.LogException(ex, ExceptionDetail.Message)
    25. 'Logger.LogException(ex, ExceptionDetail.StackTrace)
    26. 'Logger.LogException(ex, ExceptionDetail.Source)
    27. 'Logger.LogException(ex, ExceptionDetail.TargetSite)
    28. 'Logger.LogException(ex, ExceptionDetail.InnerException)
    29. 'Logger.LogException(ex, ExceptionDetail.Data)
    30. End Try
    31. End Sub
    32. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    33. Logger.OpenLogFile()
    34. End Sub
    35. End Class


    Die Logger-Class:

    VB.NET-Quellcode

    1. ' Definiert die verschiedenen Log-Level
    2. Public Enum LogLevel
    3. Debug
    4. Info
    5. Warning
    6. Failure ' "Failure" als Ersatz für "Error"
    7. Critical
    8. End Enum
    9. ' Definiert die verschiedenen Detailoptionen für eine Exception
    10. Public Enum ExceptionDetail
    11. Message ' Die Fehlermeldung der Exception
    12. StackTrace ' Der Aufrufstapel (Stack Trace) zum Zeitpunkt des Fehlers
    13. Source ' Die Quelle der Exception
    14. TargetSite ' Die Methode, die die Exception ausgelöst hat
    15. InnerException ' Eine möglicherweise vorhandene innere Exception
    16. Data ' Benutzerdefinierte Informationen zur Exception
    17. 'CustomEx ' Benutzerdefinierte Zusatzinformationen
    18. End Enum
    19. ''' <summary>
    20. ''' Klasse zur Protokollierung von Ereignissen und Ausnahmen in einer Log-Datei.
    21. ''' Bietet Funktionen zum Hinzufügen von Logeinträgen verschiedener Ebenen, zum Protokollieren von Ausnahmen
    22. ''' mit verschiedenen Detailoptionen und zum Öffnen der Log-Datei in einer Anwendung.
    23. ''' </summary>
    24. Public Class EventReportLogger
    25. ' Das Event, das bei Hinzufügen eines Logeintrags abonniert werden kann
    26. Public Event LogAdded(ByVal logEntry As String, ByVal category As String)
    27. ' Pfad und Level-Einstellungen für das Loggen
    28. Private ReadOnly executablePath As String = Application.ExecutablePath
    29. Private ReadOnly logFile As String = String.Format("EventReport{0:MM.yyyy}.txt", DateTime.Now)
    30. Private ReadOnly logFilePath As String
    31. Private _minLogLevel As LogLevel = LogLevel.Debug
    32. ' Eigenschaft, um das minimale Log-Level zu setzen oder abzurufen
    33. Public Property MinLogLevel As LogLevel
    34. Get
    35. Return _minLogLevel
    36. End Get
    37. Set(value As LogLevel)
    38. _minLogLevel = value
    39. End Set
    40. End Property
    41. ' Konstruktor, der den Pfad für das Log-Datei basierend auf dem aktuellen Datum setzt
    42. Public Sub New()
    43. logFilePath = Path.Combine(Path.GetDirectoryName(executablePath), logFile)
    44. End Sub
    45. ' Methode zum Hinzufügen eines Logeintrags mit dem angegebenen Level und der Nachricht
    46. Public Sub AddLogEntry(ByVal level As LogLevel, ByVal message As String)
    47. If level >= MinLogLevel Then
    48. Dim category As String = level.ToString()
    49. Dim logEntry As String = String.Format("[{0}] {1:dd.MM.yyyy HH:mm:ss}{2}{3}{2}", category, DateTime.Now, Environment.NewLine, message)
    50. SaveLogToFile(logEntry)
    51. RaiseEvent LogAdded(logEntry, category)
    52. End If
    53. End Sub
    54. ' Methode zum Speichern des Logeintrags in die Log-Datei
    55. Private Sub SaveLogToFile(ByVal logEntry As String)
    56. Try
    57. Using writer As New StreamWriter(logFilePath, True)
    58. writer.WriteLine(logEntry)
    59. End Using
    60. Catch ex As Exception
    61. ' Zeigt eine Fehlermeldung an, wenn das Speichern fehlschlägt
    62. MessageBox.Show("Fehler beim Speichern von: " & logFilePath & Environment.NewLine & ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    63. End Try
    64. End Sub
    65. ' Methode zum Protokollieren von Exceptions basierend auf verschiedenen Detailoptionen
    66. Public Sub LogException(ByVal ex As Exception, ByVal detail As ExceptionDetail)
    67. Select Case detail
    68. Case ExceptionDetail.Message
    69. AddLogEntry(LogLevel.Failure, ex.Message)
    70. Case ExceptionDetail.StackTrace
    71. AddLogEntry(LogLevel.Failure, ex.StackTrace)
    72. Case ExceptionDetail.Source
    73. AddLogEntry(LogLevel.Failure, ex.Source.ToString())
    74. Case ExceptionDetail.TargetSite
    75. If ex.TargetSite IsNot Nothing Then
    76. AddLogEntry(LogLevel.Failure, ex.TargetSite.ToString())
    77. End If
    78. Case ExceptionDetail.InnerException
    79. If ex.InnerException IsNot Nothing Then
    80. AddLogEntry(LogLevel.Failure, ex.InnerException.StackTrace)
    81. End If
    82. Case ExceptionDetail.Data
    83. For Each key As Object In ex.Data.Keys
    84. ' Loggt benutzerdefinierte Informationen zur Exception
    85. AddLogEntry(LogLevel.Failure, String.Format("{0}: {1}", key, ex.Data(key)))
    86. Next
    87. End Select
    88. End Sub
    89. ' Methode zum Öffnen des Logfiles in einer Anwendung
    90. Public Sub OpenLogFile()
    91. Try
    92. If File.Exists(logFilePath) Then
    93. Process.Start(logFilePath)
    94. Else
    95. MessageBox.Show("Log-Datei existiert nicht.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    96. End If
    97. Catch ex As Exception
    98. MessageBox.Show("Fehler beim Öffnen der Log-Datei: " & ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    99. End Try
    100. End Sub
    101. End Class

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    nur Schönheitsanmerkungen:

    Events sollten (nicht müssen) der EventHandler-Signatur entsprechen.
    Beispiel:

    VB.NET-Quellcode

    1. Event MyEvent As EventHandler(Of MyEventArgs)
    2. Class MyEventArgs : Inherits EventArgs
    3. '… hier zusätzliche Properties etc.
    4. End Class
    5. Sub EventHandlerMethod(sender As Object, e As MyEventArgs)


    Wie @siycah schon schrieb: Nutze interpolierte Strings statt String.Format.

    ByVal kann man weglassen
    im Setter von Properties kann man den Parameter weglassen:

    VB.NET-Quellcode

    1. Set(value As LogLevel)
    2. _minLogLevel = value
    3. End Set
    kann auch so geschrieben werden:

    VB.NET-Quellcode

    1. Set
    2. _minLogLevel = value
    3. End Set


    Zeile#67: Catch ex As Exception: Fange nur Exceptions ab, die Du kennst und sinnvoll bearbeiten kannst.

    Zeile#53: Das schrieb @siycah ebenfalls: nutze eine eine If-Umkehrung, um die Übersicht zu verbessern bzw. den Code etwas zu vereinfachen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Grundsätzlich stimme ich allem zu, was @VaporiZed bisher geschrieben hat.

    VaporiZed schrieb:

    ByVal kann man weglassen

    Das hier ist allerdings eine Sache, die mit Bedacht getan werden sollte.

    Bei VB weiß ich es nicht, aber bei C# hängt der Default immer vom Typen ab. Bei C++ ist es sogar knallhart so, wenn du nicht explizit eine Reference (oder einen Pointer) übergibst, kopierst du die Werte.
    Das kann u.U. zu Performanceproblemen führen, vor allem bei komplexen Objekten.

    Bei .net gibt's erstmal zwei verschiedene Arten von Objekten: Value Types und Reference Types.
    Der Unterschied liegt darin, wie diese verteilt werden.

    V.a. bei Parametern.

    Value Types werden (außer explizit durch ByRef oder ref durch den Programmierer spezifiziert) immer per value kopiert. Das heißt ganz konkret, du nimmst den kompletten Block Speicher, wo das Objekt liegt, kopierst den und fügst den im prinzip neu ein. Ähnlich wie CTRL+C/CTRL+V.
    Mit deinem ​ByVal Exception kopierst du also das gesamte Objekt mit allen Unterobjekten. Das kann entweder ein Shallow Copy oder ein Deep Copy sein, je nachdem, wie das bei dem Objekt eingerichtet wurde.

    Bei Reference Types ist es anders. Da übergibst du eine Referenz auf das Objekt; es ist quasi nichts anderes als ein Pointer.
    Also ein 32/64bit (4/8 Byte) Integer, der auf eine Adresse im Speicher zeigt.
    Du sagst deiner Methode also am Ende nur, wo der zu verwendende Speicher liegt.
    Das spart Zeit und kostet weniger (Speicher).

    Das ist jetzt eine ganz Oberflächliche Erklärung gewesen. Da gibt's zahlreiche Artikel zu, die das viel besser erklären als ich gerade.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)

    Microsoft schrieb:

    Wenn kein Modifizierer angegeben ist, ist ByVal der Standard. …
    Hinweis
    Daher müssen Sie das Schlüsselwort ByVal nicht explizit in Methodensignaturen angeben. Sie erzeugt in der Regel einen ausführlichen Code und führt häufig dazu, dass das ByRef-Schlüsselwort übersehen wird, das nicht Standard ist.


    siehe auch: Stilregel "ByVal entfernen (IDE0081)" von Microsoft

    Dass man bei Referenztypen manchmal mit ByRef arbeiten muss, hatte ich auch mal mitbekommen: Dispose und Nothing in einer Extension-Prozedur

    siycah schrieb:

    Mit deinem ByVal Exception kopierst du also das gesamte Objekt mit allen Unterobjekten.
    Das bezweifel ich grad n bisken, weil es als Klassenobjekt ein Referenztyp sein dürfte und damit Deine Pointerlogik greift.
    Bilder
    • ByVal.png

      10,22 kB, 562×142, 50 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Amelie schrieb:

    VB.NET-Quellcode

    1. Private ReadOnly logFile As String = String.Format("EventReport{0:MM.yyyy}.txt", DateTime.Now)
    Eine Datei pro Monat?
    Wenn Du das Datum anders herun schreibst: yyyy.MM sind die Dateien alphabetisch und chronologisch gleich sortiert.
    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!

    siycah schrieb:

    Mit deinem ​ByVal Exception kopierst du also das gesamte Objekt mit allen Unterobjekten.
    Das stimmt nicht.
    Es wird der Objekt-Zeiger kopiert, in anderen Worten: Die Referenz auf das Exception-Objekt.
    Weil Exception ist ein Referenz-Typ.

    @Amelie:
    • Was du gebastelt hast ist ein Logger, kein EventLogger. Ein EventLogger ist glaub was anderes (aber ganz sicher bin ich nicht).
    • Nachwievor ist die mehr als Hälfte deiner Kommentation schmerzhaft überflüssig, und damit giftig.
    • Ein Logger sollte vlt. besser Shared sein bzw ein Singleton
      Stell dir bei deiner Konstruktion mal vor, dass mehrere Forms offen sind und loggen wollen - gibt das dann keine Datei-Zugriffs-Konflikte?
    • Ein Log-Eintrag sollte automatisch den Zeitpunkt mit-loggen.
      Aber gut - das hängt vom Bedarf ab - ich gehe von Loggern aus, wie wir sie benutzen, vlt. ist dein Logger für andere Zwecke gedacht.
    @VaporiZed, @ErfinderDesRades

    Ihr habt natürlich Recht - mein Fehler. Dabei habe ich extra nochmal gesucht um mir sicher zu sein. Schön zu sehen, dass im Internet immer solch' widersprüchlichen Infos stehen :thumbdown:
    War mir bei VB überhaupt nimmer sicher, wie das gehandelt wird. Naja, manchmal muss auch was blödes rausrutschen ;)
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    Moin moin

    Also ich bekomme diese beide "Warnungen" nicht in den Griff. ;(
    Das Event als solches funktioniert.

    VB.NET-Quellcode

    1. Public Delegate Sub EventReportHandler(sender As Object, e As EventReportLogger)
    2. Public Class EventReportLogger
    3. Inherits EventArgs
    4. ' Das Event, das bei Hinzufügen eines Logeintrags abonniert werden kann
    5. Public Event LogAdded(ByVal LogEntry As String, ByVal Category As String)
    6. Protected Sub RaiseLogAdded(sender As Object, e As EventArgs)
    7. RaiseEvent LogAdded(LogEntry, Category)
    8. End Sub
    9. Public Property LogEntry As String
    10. Public Property Category As String
    11. ' Pfad und Level-Einstellungen für das Loggen
    12. Private ReadOnly executablePath As String = Application.ExecutablePath
    13. Private ReadOnly logFile As String = String.Format("EventReport{0:yyyy.MM}.txt", DateTime.Now)
    14. Private ReadOnly logFilePath As String
    15. Private _minLogLevel As LogLevel = LogLevel.Debug
    16. Public Sub AddLogEntry(level As LogLevel, message As String)
    17. If level >= MinLogLevel Then
    18. Category = level.ToString()
    19. LogEntry = String.Format("[{0}] {1:dd.MM.yyyy HH:mm:ss}{2}{3}{2}", Category, DateTime.Now, Environment.NewLine, message)
    20. SaveLogToFile(LogEntry)
    21. RaiseEvent LogAdded(LogEntry, Category)
    22. End If
    23. End Sub


    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Warnung CA1009 Deklarieren Sie den zweiten Parameter von "'EventReportLogger.LogAddedEventHandler'" als EventArgs oder als Instanz eines Typs, durch den EventArgs erweitert wird, mit dem Namen "e". ReportLogger A:\Entwicklung\2023\ReportLogger\ReportLogger\clsReportLogger.vb 40 Aktiv
    Warnung CA1009 Deklarieren Sie den ersten Parameter von "'EventReportLogger.LogAddedEventHandler'" als Objekt mit dem Namen "sender". ReportLogger A:\Entwicklung\2023\ReportLogger\ReportLogger\clsReportLogger.vb 40 Aktiv
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Der möchte, dass du ​Public Event LogAdded(ByVal LogEntry As String, ByVal Category As String)

    Durch ein Delegate mit folgender Signatur änderst: ​public event LogAdded(sender as object, e as LogAddedEventArgs.

    In dem ​LogAddedEventArgs erbst du dann von ​EventArgs und fügst dann ​LogEntry und ​Category als Properties ein.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    So, habe es nun hinbekommen. :/
    Einen simplen Einzeiler gegen viel Code nur um eine "Warnung" nicht einmal ein "Fehler" auszutauschen, finde ich echt seltsam.

    Wenn ich das ganze nun richtig verstanden habe, müsste ich für ein weiteres Event, wieder einen weiteren Delegaten erstellen und ggf auch eine weiter Klasse??

    VB.NET-Quellcode

    1. ' Ein simpler Einzeiler
    2. Public Event LogAdded(ByVal logEntry As String, ByVal category As String)


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Delegate Sub LogAddedEventHandler(sender As Object, e As LogAddedEventArgs)
    2. Public Class LogAddedEventArgs
    3. Inherits EventArgs
    4. Public Property LogEntry As String
    5. Public Property Category As String
    6. Public Sub New(logEntry As String, category As String)
    7. logEntry = logEntry
    8. category = category
    9. End Sub
    10. End Class
    11. Public Class EventReportLogger
    12. ' Event mit LogAddedEventArgs
    13. Public Event LogAdded As EventHandler(Of LogAddedEventArgs)
    14. '..
    15. '....
    16. '..
    17. ' Methode zum Hinzufügen eines Logeintrags mit dem angegebenen Level und der Nachricht
    18. Public Sub AddLogEntry(level As LogLevel, message As String)
    19. If level >= MinLogLevel Then
    20. Dim category = level.ToString()
    21. Dim logEntry = String.Format("[{0}] {1:dd.MM.yyyy HH:mm:ss}{2}{3}{2}", category, DateTime.Now, Environment.NewLine, message)
    22. SaveLogToFile(logEntry)
    23. ' Direkter Aufruf des Events mit LogAddedEventArgs
    24. RaiseEvent LogAdded(Me, New LogAddedEventArgs(logEntry, category))
    25. End If
    26. End Sub


    VB.NET-Quellcode

    1. 'Auf dem FrmMain
    2. Private Sub LoggerHandler(sender As Object, e As LogAddedEventArgs) Handles Logger.LogAdded
    3. lblEventresult.Text = $"{e.LogEntry}-{e.Category}"
    4. End Sub

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Einen simplen Einzeiler gegen viel Code nur um eine "Warnung" nicht einmal ein "Fehler" auszutauschen, finde ich echt seltsam.


    Wenn du deinen Compiler richtig einstellst, ist das auch ein Fehler. Stichwort: ​-Werror.
    Hier sind mehr Informationen: learn.microsoft.com/en-us/dotn…r-options/errors-warnings

    Amelie schrieb:

    Wenn ich das ganze nun richtig verstanden habe, müsste ich für ein weiteres Event, wieder einen weiteren Delegaten erstellen und ggf auch eine weiter Klasse??


    Außer du kannst deinen ​EventArgs wiederverwenden, ja.
    Aber so macht es das restliche Framework auch. Du solltest deinen Code möglichst so schreiben, dass du nicht ganz davon abweichst.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)

    Amelie schrieb:

    Einen simplen Einzeiler gegen viel Code nur um eine "Warnung" nicht einmal
    ein "Fehler" auszutauschen, finde ich echt seltsam.
    Ja, das finde ich auch sehr umständlich gelöst.
    Aber global gesehen ist dieser Pattern schon ziemlich nützlich.

    Amelie schrieb:

    Wenn ich das ganze nun richtig verstanden habe, müsste ich für ein weiteres Event, wieder einen weiteren Delegaten erstellen und ggf auch eine weiter Klasse??


    ich zb bevorzuge Events ohne EventArgs:

    VB.NET-Quellcode

    1. Public Event BlaDone as EventHandler





    Oder aber du verzichtest auf das Event.
    Wie gesagt: Nur das programmieren, was du brauchst - nicht alles was du kannst.
    Und ich sehe nicht, dass du das Event grad brauchst.
    @siycah
    Ich habe das Häkchen "Warnungen als Fehler" immer drin. Hatte mir @VaporiZed mal vor einiger Zeit gesagt.
    Die Warnungen von heute kamen durch die "Codeanalyse" in VS2017. Muss mal guggen ob es da wieder etwas anders einzustellen gibt.

    ​Aber so macht es das restliche Framework auch.

    Manchmal denke ich, dass da mit meiner Logik viel "unnützer" Code gebaut wird. Aber ich versuche es zu beherzigen. :thumbup:

    @ErfinderDesRades
    ​Nur das programmieren, was du brauchst

    Ja gebe dir Recht, nur hier war es nochmal eine gute Übung.

    Ich denke bei kleinen Programmen, kann ich auch so einen "Einzeiler" für ein Event benutzen :?:

    Noch ein Nachtrag zu gestern: "Logger" vs "EventLogger"
    Ja im Grunde hast du Recht, es ist ein Logger.

    Ich habe den Namen gewählt, weil ich damit bestimmte "Events" die ich in meinen Programmen benutze, aufzeichnen möchte, damit ich ggf nachvollziehen kann wo irgendwelche Fehler etc auftreten.
    ​Me.Amelie = schlechteNamenswahl :D

    ​Ein Logger sollte vlt. besser Shared sein bzw ein Singleton

    Da muss ich erstmal drüber lesen... später.. sonst platzt mein Kopf.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Wofür einen Delegate?
    Das mit den eigenen EventArgs-Klassen scheint anfänglich Overkill, aber sind sehr praktisch, weil Du damit standardisierte Datenpakete in Deinen Programmen verwendest (je umfangreicher Du das nutzt, desto mehr wirst Du das merken) und Du kannst vom EventHandler die Daten ändern lassen und vom Sender danach auswerten. Davon macht z.B. WinForms Gebrauch, wenn man das Schließen eines Forms im FormClosing-EventHandler abbrechen will, indem man e.Cancel = True setzt. Der Empfänger ändert also den Wert des vom Sender geschickten Pakets und der Sender wertet die Daten danach aus. Das ginge mit einfachen Variablen dann nur über ByRef. Denn eine Function kannst Du als EventHandler nicht als Informationsquelle für den Sender verwenden.
    Auch kannst Du im EventHandler Properties/Teile des Datenpakets erstellen, wenn also der Sender das Event feuert und der Empfänger/EventHandler eine Property mit New belegen soll. Das ginge auch nicht (einfach) mit normalen Werten. Daher sind die EventArgs-Klassen besser als ihr hiesiger Ruf.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()