In Visual Basic (VB.NET) delegati sono un tipo che contiene un riferimento a un metodo con una specifica firma, e servono come base per la gestione degli eventi. Eventi sono costruiti sui delegati, permettendo agli oggetti di notificare altri sui cambiamenti avvenuti.
Per eventi standard si usano delegati già definiti, ad esempio, EventHandler, mentre per eventi personalizzati si può definire un proprio delegato con la firma desiderata:
'Dichiarazione di un delegato e evento personalizzato Public Delegate Sub ChangedEventHandler(sender As Object, e As EventArgs) Public Event Changed As ChangedEventHandler 'Utilizzo dell'evento Public Sub OnChanged() RaiseEvent Changed(Me, EventArgs.Empty) End Sub
Sfumature:
Perché un evento in Visual Basic non può essere chiamato al di fuori della classe, anche se dichiarato come Public?
Risposta: Nonostante il modificatore di accesso Public, un evento può solo essere "iscritto" o "disiscritto" dall'esterno della classe, ma può essere chiamato (RaiseEvent) solo all'interno della classe — questa è una specificità del linguaggio, che garantisce incapsulamento e controllo sulla distribuzione degli eventi. Ad esempio:
Public Class Foo Public Event MyEvent() End Class Dim f As New Foo() ' Non si può fare: f.RaiseEvent MyEvent() — il compilatore non lo permette.
Storia
Progetto Windows Forms: Un sviluppatore ha tentato di chiamare l'evento "DataUpdated" dall'esterno della classe di dati, per aggiornare l'interfaccia utente. Non ci è riuscito, l'evento non è stato gestito, è stata necessaria la rifattorizzazione dell'architettura e la revisione della logica a causa di una comprensione errata della portata dell'evento.
Storia
Servizio Web: Quando è stato dichiarato il delegato, è stata omessa una variabile nella firma. L'evento si è iscritto, ma è stato chiamato con un errore di runtime — l'abbonato si aspettava un argomento, mentre la chiamata veniva eseguita con due.
Storia
Plugin per 1C: Gli sviluppatori hanno utilizzato FieldInfo.SetValue per simulare la chiamata a RaiseEvent. Questo ha causato uno stato incoerente dell'interfaccia e un crash durante l'aggiornamento dell'assembly.