In Visual Basic (VB.NET) sind Delegaten Typen, die einen Verweis auf eine Methode mit einer bestimmten Signatur enthalten und die Grundlage für die Ereignisbehandlung bilden. Ereignisse basieren auf Delegaten und ermöglichen es Objekten, andere über aufgetretene Änderungen zu benachrichtigen.
Für Standardereignisse werden bereits definierte Delegaten verwendet, zum Beispiel EventHandler, während für benutzerdefinierte Ereignisse ein eigener Delegat mit der gewünschten Signatur definiert werden kann:
'Erklärung eines benutzerdefinierten Delegaten und Ereignisses Public Delegate Sub ChangedEventHandler(sender As Object, e As EventArgs) Public Event Changed As ChangedEventHandler 'Verwendung des Ereignisses Public Sub OnChanged() RaiseEvent Changed(Me, EventArgs.Empty) End Sub
Nuancen:
Warum kann ein Ereignis in Visual Basic nicht außerhalb der Klasse ausgelöst werden, selbst wenn es als Public deklariert ist?
Antwort: Trotz des Zugriffsmodifikators Public kann ein Ereignis von außen nur „abonniert“ oder „abgemeldet“ werden, aber die Auslösung (RaiseEvent) kann nur innerhalb der Klasse erfolgen – das ist eine Besonderheit der Sprache, die Kapselung und Kontrolle über die Verbreitung von Ereignissen gewährleistet. Zum Beispiel:
Public Class Foo Public Event MyEvent() End Class Dim f As New Foo() ' Das ist nicht erlaubt: f.RaiseEvent MyEvent() — der Compiler lässt dies nicht zu.
Geschichte
Windows Forms-Projekt: Der Entwickler versuchte, das Ereignis „DataUpdated“ von außerhalb der Datenklasse auszulösen, um die UI zu aktualisieren. Es war nicht möglich, das Ereignis wurde nicht verarbeitet, was dazu führte, dass die Architektur refaktoriert und die Logik aufgrund eines falschen Verständnisses des Sichtbarkeitsbereichs des Ereignisses geändert werden musste.
Geschichte
Webdienst: Bei der Deklaration des Delegaten wurde eine Variable in der Signatur weggelassen. Das Ereignis wurde abonniert, aber es trat beim Auslösen zur Laufzeit ein Fehler auf – der Abonnent erwartete ein Argument, während der Aufruf mit zwei durchgeführt wurde.
Geschichte
Plugin für 1C: Die Entwickler verwendeten FieldInfo.SetValue, um einen Aufruf von RaiseEvent zu imitieren. Dies führte zu einer Inkonsistenz im Zustand der Schnittstelle und einem Crash bei der Aktualisierung des Assemblies.