Introduction aux événements
Les événements sont, comme les délégués, un mécanisme de liaison tardive. En fait, les événements reposent sur la prise en charge linguistique des délégués.
Ils permettent à un objet de signaler (à tous les composants du système intéressés), que quelque chose s’est produit. Tous les autres composants peuvent s’abonner à l’événement et être averti quand un événement est déclenché.
Vous avez sans doute déjà utilisé des événements durant vos tâches de programmation. De nombreux systèmes graphiques ont un modèle d’événement pour signaler l’interaction utilisateur. Ces événements signalent les mouvements de la souris, les pressions sur des boutons et autres interactions similaires. C’est l’un des scénarios les plus courants, mais certainement pas le seul, où des événements sont utilisés.
Vous pouvez définir les événements qui doivent être déclenchés pour vos classes. Quand vous travaillez avec des événements, vous devez prendre en compte le fait qu’il se peut qu’aucun objet ne soit inscrit pour un événement particulier. Vous devez écrire votre code pour qu’il ne déclenche pas d’événement quand aucun détecteur n’est configuré.
L’abonnement à un événement crée également un couplage entre deux objets (la source de l’événement et le récepteur d’événements). Vous devez vérifier que le récepteur d’événements annule l’abonnement à la source de l’événement quand il n’est plus intéressé par les événements.
Objectifs de conception pour la prise en charge des événements
En matière d’événements, la conception du langage vise les objectifs suivants :
Un couplage minimal entre une source d’événements et un récepteur d’événements doit être possible. Ces deux composants peuvent ne pas avoir été écrits par la même organisation, et peuvent même être mis à jour d’après une planification totalement différente.
La procédure d’abonnement à un événement et de désabonnement de celui-ci doit être très simple.
Les sources d’événements doivent prendre en charge plusieurs abonnés aux événements. Elles doivent aussi prendre en charge les scénarios où aucun abonné aux événements n’est attaché.
Vous pouvez constater que les objectifs pour les événements sont très similaires aux objectifs pour les délégués. C’est pourquoi la prise en charge linguistique des événements repose sur la prise en charge linguistique des délégués.
Prise en charge du langage des événements
La syntaxe de définition des événements, et d’abonnement ou d’annulation des abonnements, est une extension de la syntaxe des délégués.
Pour définir un événement, vous devez utiliser le mot clé event
:
public event EventHandler<FileListArgs> Progress;
Le type de l’événement (EventHandler<FileListArgs>
dans cet exemple) doit être un type délégué. Vous devez respecter plusieurs conventions lors de la déclaration d’un événement. En général, le type délégué d’événement a un retour void.
Les déclarations d’événements doivent être un verbe ou une phrase verbale.
Utilisez le passé lorsque l’événement signale quelque chose qui s’est produit. Utilisez un verbe au présent (par exemple, Closing
) pour signaler quelque chose qui est sur le point de se produire. Souvent, le présent indique que votre classe prend en charge un type de comportement de personnalisation. L’un des scénarios les plus courants consiste à prendre en charge l’annulation. Par exemple, un événement Closing
peut inclure un argument qui indique si l’opération de fermeture doit continuer ou non. D’autres scénarios peuvent permettre aux appelants de modifier le comportement en mettant à jour les propriétés des arguments de l’événement. Vous pouvez déclencher un événement pour indiquer une action suivante qu’un algorithme effectuera. Le gestionnaire d’événements peut imposer une action différente en modifiant les propriétés de l’argument de l’événement.
Quand vous souhaitez déclencher l’événement, vous appelez les gestionnaires d’événements à l’aide de la syntaxe d’appel de délégué :
Progress?.Invoke(this, new FileListArgs(file));
Comme indiqué dans la section sur les délégués, l’opérateur ?. permet de s’assurer facilement que vous n’essayez pas de déclencher l’événement quand il n’y a aucun abonné à cet événement.
Vous vous abonnez à un événement à l’aide de l’opérateur +=
:
EventHandler<FileListArgs> onProgress = (sender, eventArgs) =>
Console.WriteLine(eventArgs.FoundFile);
fileLister.Progress += onProgress;
La méthode du gestionnaire comporte en général le préfixe « On » suivi du nom de l’événement, comme indiqué ci-dessus.
Vous pouvez vous désinscrire à l’aide de l’opérateur -=
:
fileLister.Progress -= onProgress;
Vous devez impérativement déclarer une variable locale pour l’expression qui représente le gestionnaire d’événements. Cela garantit que le désabonnement supprime le gestionnaire. Si au lieu de cela vous utilisez le corps de l’expression lambda, vous essayez de supprimer un gestionnaire qui n’a jamais été attaché, ce qui ne fait rien.
Dans l’article suivant, vous en apprendrez davantage sur les modèles d’événements les plus courants et sur les différentes variantes de cet exemple.