In Visual Basic (VB.NET) zijn delegaten een type dat een verwijzing naar een methode met een bepaalde handtekening bevat en de basis vormt voor het afhandelen van gebeurtenissen. Gebeurtenissen zijn gebouwd op delegaten, waardoor objecten andere objecten kunnen informeren over opgetreden wijzigingen.
Voor standaard gebeurtenissen worden al gedefinieerde delegaten gebruikt, zoals EventHandler, en voor gebruikersspecifieke gebeurtenissen kan een eigen delegaat met de vereiste handtekening worden gedefinieerd:
'Declaratie van een gebruikersspecifieke delegaat en gebeurtenis Public Delegate Sub ChangedEventHandler(sender As Object, e As EventArgs) Public Event Changed As ChangedEventHandler 'Gebruik van de gebeurtenis Public Sub OnChanged() RaiseEvent Changed(Me, EventArgs.Empty) End Sub
Fijnere punten:
Waarom kan een gebeurtenis in Visual Basic niet buiten de klasse worden opgeroepen, zelfs als deze is gedeclareerd als Public?
Antwoord: Ondanks de toegangsspecifiek Public kan een gebeurtenis alleen "geabonneerd" of "afgemeld" worden van buiten de klasse, maar kan alleen binnen de klasse worden opgeroepen (RaiseEvent) — dit is een specificiteit van de taal die encapsulatie en controle over het verzenden van gebeurtenissen waarborgt. Bijvoorbeeld:
Public Class Foo Public Event MyEvent() End Class Dim f As New Foo() ' Dit is niet toegestaan: f.RaiseEvent MyEvent() — de compiler staat dit niet toe.
Verhaal
Windows Forms-project: De ontwikkelaar probeerde de gebeurtenis "DataUpdated" van buiten de gegevensklasse aan te roepen om de UI bij te werken. Het lukte niet, de gebeurtenis werd niet afgehandeld, de architectuur moest worden herzien, de logica moest worden aangepast vanwege een verkeerd begrip van de reikwijdte van de gebeurtenis.
Verhaal
Webservice: Bij het declareren van de delegaat werd een variabele in de handtekening weggelaten. De gebeurtenis schreef zich in, maar werd met een runtime-fout aangeroepen — de abonnee verwachtte één argument, maar de aanroep ging met twee.
Verhaal
Plugin voor 1C: Ontwikkelaars gebruikten FieldInfo.SetValue om een RaiseEvent-aanroep te simuleren. Dit veroorzaakte een inconsistente status van de interface en een crash bij de update van de assembly.