Délégués et Événements
Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy — leçon 43 sur 70.
Un délégué est un type qui représente une référence à une méthode. Considérez-le comme une variable qui contient une méthode au lieu de données. Cela vous permet de passer des méthodes en tant qu'arguments, de les stocker dans des collections et de les appeler dynamiquement.
Vous déclarez un délégué en spécifiant la signature de la méthode qu'il peut référencer :
public delegate void Notify(string message);
public class Publisher
{
public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}
// Utilisation
Notify notifier = new Publisher().SendAlert;
notifier("System started"); // Alert: System startedLes événements s'appuient sur les délégués pour implémenter le modèle publication-abonnement. Une classe déclenche un événement, et d'autres classes peuvent s'abonner pour recevoir des notifications. Le mot-clé event limite la manière dont le délégué peut être utilisé : les abonnés peuvent uniquement ajouter ou supprimer des gestionnaires, mais ne peuvent pas invoquer l'événement directement.
public class Button
{
public event Action Clicked;
public void Click()
{
Clicked?.Invoke(); // Notifier tous les abonnés
}
}
// S'abonner
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click(); // Le bouton a été cliqué !L'opérateur += permet de s'abonner à un gestionnaire, tandis que -= permet de s'en désabonner. Le modèle ?.Invoke() appelle l'événement en toute sécurité uniquement s'il y a des abonnés. Les événements sont fondamentaux pour les applications GUI, les moteurs de jeu et tout système où les objets doivent réagir aux changements sans couplage étroit.
Défi
FacileConstruisons un système de surveillance de la température qui utilise des délégués et des événements pour notifier les abonnés chaque fois que la température change. C'est un exemple classique du modèle publication-abonnement que les événements permettent de mettre en œuvre si élégamment.
Vous organiserez votre code sur deux fichiers :
TemperatureMonitor.cs: Créez une classeTemperatureMonitordans l'espace de nomsMonitoringqui agit comme l'éditeur. Votre moniteur doit :- Avoir un champ privé pour stocker la température actuelle
- Déclarer un événement utilisant
Action<int>appeléTemperatureChangedqui se déclenche chaque fois que la température est mise à jour - Avoir une propriété
Temperature(int) où le setter met à jour le champ privé et déclenche l'événement avec la nouvelle valeur de température
?.Invoke()pour déclencher l'événement en toute sécurité uniquement lorsqu'il y a des abonnés.Program.cs: Dans votre fichier principal, créez unTemperatureMonitoret abonnez deux gestionnaires différents à son événementTemperatureChanged:- Un gestionnaire qui affiche :
Alert: Temperature is now {value} degrees - Un autre gestionnaire qui affiche :
Logged: {value}
- Un gestionnaire qui affiche :
Vous recevrez deux entrées :
- Première valeur de température (entier)
- Deuxième valeur de température (entier)
Par exemple, si les entrées sont 25 et 30, la sortie devrait être :
Alert: Temperature is now 25 degrees
Logged: 25
Alert: Temperature is now 30 degrees
Logged: 30Remarquez comment la définition de la propriété Temperature notifie automatiquement tous les abonnés - le moniteur n'a pas besoin de savoir qui écoute. C'est toute la beauté de l'approche pilotée par les événements !
Aide-mémoire
Un délégué (delegate) est un type qui représente une référence à une méthode, vous permettant de passer des méthodes comme arguments, de les stocker dans des collections et de les appeler dynamiquement.
Déclarez un délégué en spécifiant la signature de la méthode :
public delegate void Notify(string message);
public class Publisher
{
public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}
// Usage
Notify notifier = new Publisher().SendAlert;
notifier("System started"); // Alert: System startedLes événements (events) implémentent le modèle publication-abonnement en utilisant des délégués. Le mot-clé event restreint l'utilisation du délégué - les abonnés peuvent uniquement ajouter ou supprimer des gestionnaires, et non invoquer l'événement directement.
public class Button
{
public event Action Clicked;
public void Click()
{
Clicked?.Invoke(); // Notify all subscribers
}
}
// Subscribing
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click(); // Button was clicked!Utilisez += pour s'abonner à un gestionnaire et -= pour se désabonner. Le modèle ?.Invoke() appelle l'événement en toute sécurité uniquement s'il y a des abonnés.
Essayez vous-même
using System;
using Monitoring;
class Program
{
public static void Main(string[] args)
{
// Lire l'entrée
int temp1 = Convert.ToInt32(Console.ReadLine());
int temp2 = Convert.ToInt32(Console.ReadLine());
// TODO: Créer une instance de TemperatureMonitor
// TODO: S'abonner à un gestionnaire qui affiche : "Alert: Temperature is now {value} degrees"
// TODO: S'abonner à un autre gestionnaire qui affiche : "Logged: {value}"
// TODO: Régler la température à temp1
// TODO: Régler la température à temp2
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesEspaces de noms et directivesIntro aux classes et objetsLe mot-clé 'this'Méthodes et paramètresChamps vs PropriétésConstructeursInitialiseurs d'objetsRécapitulatif - Calculatrice simple4Héritage
Syntaxe de base de l'héritage (:)Le mot-clé 'base'Mots-clés Virtual & OverrideClasses scelléesLa classe de base 'object'Récapitulatif - Hiérarchie des employés7Fonctionnalités avancées
Surcharge d'opérateursIndexeurs (this[])Redéfinition de ToString()Méthodes d'extensionRécapitulatif - Liste personnalisée10Patrons de conception - Partie 1
Introduction aux patrons de conceptionSingleton Thread-SafePatron FabriquePatron Observateur (Événements)Patron Stratégie2Propriétés et membres statiques
Propriétés auto-implémentéesPropriétés en lecture/écriture seuleChamps et méthodes statiquesClasses statiquesMembres à corps d'expression5Polymorphisme & Interfaces
Polymorphisme : Compilation vs ExécutionInterface vs Classe AbstraiteInterfaces MultiplesInterfaces ExplicitesUpcasting & DowncastingRécapitulatif - Calculateur de Formes8Concepts avancés de la POO
Composition plutôt qu'héritageGénériques (Classes et Méthodes)Délégués et ÉvénementsAttributs et RéflexionIDisposable et l'instruction usingBases de l'Injection de Dépendances11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Architecture des classes
Données d'instance vs statiquesMots-clés 'readonly' & 'const'Champs de supportRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Modificateurs d'accèsPropriétés pour l'encapsulationImplémentation du masquage de donnéesPatterns d'immuabilitéRécapitulatif - Dossiers d'étudiants12Projet : Système de gestion de bibliothèque
Structure du projetModèles Livre et Utilisateur