En Visual Basic (VB.NET), les délégations représentent un type qui contient une référence à une méthode avec une signature définie, et servent de base pour la gestion des événements. Les événements sont construits sur des délégations, permettant aux objets d'informer les autres des changements survenus.
Pour les événements standards, des délégations déjà définies sont utilisées, comme EventHandler, tandis que pour les événements personnalisés, on peut définir sa propre délégation avec la signature souhaitée :
'Déclaration d'une délégation et d'un événement personnalisés Public Delegate Sub ChangedEventHandler(sender As Object, e As EventArgs) Public Event Changed As ChangedEventHandler 'Utilisation de l'événement Public Sub OnChanged() RaiseEvent Changed(Me, EventArgs.Empty) End Sub
Subtilités :
Pourquoi un événement dans Visual Basic ne peut-il pas être appelé en dehors de la classe, même s'il est déclaré comme Public ?
Réponse : Malgré le modificateur d'accès Public, un événement ne peut être que "inscrit" ou "désinscrit" depuis l'extérieur de la classe, mais uniquement être appelé (RaiseEvent) à l'intérieur de la classe — c'est une spécificité du langage, assurant l'encapsulation et le contrôle sur la diffusion des événements. Par exemple :
Public Class Foo Public Event MyEvent() End Class Dim f As New Foo() ' Cela ne fonctionne pas : f.RaiseEvent MyEvent() — le compilateur ne permet pas cela.
Histoire
Projet Windows Forms : Un développeur a essayé d'appeler l'événement "DataUpdated" depuis l'extérieur de la classe de données pour mettre à jour l'interface utilisateur. Cela n'a pas fonctionné, l'événement n'a pas été géré, ce qui a nécessité de refactoriser l'architecture et de revisiter la logique à cause d'une mauvaise compréhension de la portée de l'événement.
Histoire
Service Web : Lors de la déclaration de la délégation, une variable a été omise dans la signature. L'événement s'est inscrit, mais a été appelé avec une erreur d'exécution — le souscripteur s'attendait à un argument, alors que l'appel se faisait avec deux.
Histoire
Plugin pour 1C : Les développeurs ont utilisé FieldInfo.SetValue pour simuler l'appel de RaiseEvent. Cela a provoqué une désynchronisation de l'état de l'interface et un crash lors de la mise à jour de l'assemblage.