Partager via


Différenciation des délégués et des événements

Précédent

Les développeurs qui sont nouveaux dans la plateforme .NET ont souvent du mal à décider entre une conception basée sur delegates et une conception basée sur events. Le choix des délégués ou des événements est souvent difficile, car les deux fonctionnalités linguistiques sont similaires. Les événements sont même générés à l’aide de la prise en charge linguistique des délégués. Une déclaration de gestionnaire d’événements déclare un type délégué.

Les deux offrent un scénario de liaison tardive : ils activent les scénarios où un composant communique en appelant une méthode connue uniquement au moment de l’exécution. Ils prennent tous les deux en charge des méthodes d’abonnement uniques et multiples. Vous pouvez trouver ces termes sous les appellations « single cast » (diffusion unique) et « multicast » (multidiffusion). Ils prennent tous deux en charge une syntaxe similaire pour l’ajout et la suppression de gestionnaires. Enfin, le déclenchement d’un événement et l’appel d’un délégué utilisent exactement la même syntaxe d’appel de méthode. Qui plus est, elles prennent toutes deux en charge la même syntaxe de méthode Invoke() pour une utilisation avec l’opérateur ?..

Avec toutes ces similitudes, il est facile d'avoir du mal à déterminer quand utiliser quoi.

L’écoute des événements est facultative

L’élément le plus important à prendre en compte dans la détermination de la fonctionnalité de langue à utiliser est de savoir s’il doit y avoir ou non un abonné attaché. Si votre code doit appeler le code fourni par l’abonné, vous devez utiliser une conception logicielle basée sur les délégués lorsque vous devez implémenter un callback. Si votre code peut effectuer tout son travail sans appeler d’abonnés, vous devez utiliser une conception basée sur les événements.

Considérez les exemples générés pendant cette section. Le code que vous avez créé à l’aide List.Sort() doit recevoir une fonction de comparateur pour trier correctement les éléments. Des requêtes LINQ doivent être fournies avec les délégués pour identifier les éléments à retourner. Les deux ont utilisé une conception générée avec des délégués.

Prenez l’événement Progress. Il signale la progression d’une tâche. La tâche continue de continuer si des écouteurs sont présents ou non. FileSearcher s’agit d’un autre exemple. Il trouvera tous les fichiers recherchés même si aucun abonné aux événements n’est attaché. Les contrôles d’expérience utilisateur fonctionnent toujours correctement, même s’il n’y a pas d’abonnés qui écoutent les événements. Ils utilisent tous deux des conceptions basées sur des événements.

Les valeurs de retour nécessitent des délégués

Une autre considération à prendre en compte est le prototype de méthode souhaité pour votre méthode déléguée. Comme vous l'avez vu, les délégués utilisés pour les événements ont tous un type de retour void. Il existe des idiomes pour créer des gestionnaires d’événements qui transmettent des informations aux sources d’événements par le biais de la modification des propriétés de l’objet d’argument d’événement. Bien que ces idiomes fonctionnent, ils ne sont pas aussi naturels que de retourner une valeur d’une méthode.

Notez que ces deux heuristiques peuvent souvent être présentes : si votre méthode de délégué retourne une valeur, elle affecte l’algorithme d’une certaine manière.

Les événements ont un appel privé

Les classes autres que celles dans lesquelles un événement est contenu peuvent uniquement ajouter et supprimer des écouteurs d’événements ; seule la classe contenant l’événement peut appeler l’événement. Les événements sont généralement des membres de classe publique. En comparaison, les délégués sont souvent transmis en tant que paramètres et stockés en tant que membres privés de la classe, si tant est qu'ils soient stockés.

Les détecteurs d’événements ont souvent des durées de vie plus longues

Les durées de vie plus longues des écouteurs d’événements est une justification légèrement moins pertinente. Toutefois, vous pouvez constater que les conceptions basées sur des événements sont plus naturelles lorsque la source d’événement déclenche des événements sur une longue période. Vous pouvez voir des exemples de conception basée sur des événements pour les contrôles d’expérience utilisateur sur de nombreux systèmes. Une fois que vous vous abonnez à un événement, la source d’événement peut déclencher des événements tout au long de la durée de vie du programme. (Vous pouvez vous désabonner des événements lorsque vous n’en avez plus besoin.)

Comparez cela à de nombreuses conceptions basées sur les délégués, où un délégué est utilisé comme argument d'une méthode, et où le délégué n'est pas utilisé après le retour de cette méthode.

Évaluer avec soin

Les considérations ci-dessus ne sont pas des règles strictes. Au lieu de cela, ils représentent des conseils qui peuvent vous aider à décider quel choix est le meilleur pour votre utilisation particulière. Comme ils sont similaires, vous pouvez même prototyper les deux, et considérer ce qui serait plus naturel à travailler avec. Elles gèrent également toutes deux les scénarios de liaison tardive. Utilisez celui qui communique votre conception le mieux.