# Programmation C sharp/Delegates et events
## Les délégués

Un délégué (delegate en anglais) est l'équivalent .Net d'un pointeur de fonction. Son rôle est d'appeler une ou plusieurs méthodes qui peuvent varier selon le contexte.

### Syntaxe

La déclaration d'un délégué définit la signature d'une méthode, dont le type de retour est précédé du mot clé delegate.
Exemple :
Cette déclaration produit en fait une classe CompareDelegate dérivant de la classe System.Delegate. Il est donc possible de la placer en dehors de toute classe ou espace de noms, comme pour une classe normale.

### Utilisation

Ce délégué définit donc un nouveau type qui peut être utilisé en paramètre d'une méthode. L'appel à un délégué utilise la même syntaxe que celle d'une méthode.
Exemple :

### Instanciation

Une variable du type délégué peut être déclarée, comme avec une classe normale :
Initialement, cette variable vaut null car ne référence aucune méthode.

### Ajout et retrait de fonction

Un délégué est associé à une ou plusieurs méthodes qui possèdent toutes la même signature que celui-ci.
L'ajout ou le retrait de fonction se fait par les opérateurs =, += et -=.
Exemple : soit les deux méthodes suivantes :
et le délégué suivant :
Il est également possible d'utiliser la syntaxe suivante équivalente à la précédente :

### Délégué anonyme

Il est possible de créer dynamiquement la fonction associée à un délégué en utilisant la syntaxe anonyme suivante :
Exemple :
La spécification des arguments est optionnelle, à condition qu'aucun des arguments ne soit utilisé par la fonction. Ce qui ne peut être le cas si un des arguments est de type out, car la fonction doit obligatoirement lui attribuer une valeur.
Exemple :

### Les délégués du framework .Net

La plupart des délégués du framework .Net sont utilisés comme callback, c'est à dire appelés quand un événement se produit (timer, opération terminée, exécution d'un thread, ...). La signature de ces délégués comporte en général un paramètre nommé state de type object. Ce paramètre correspond à la valeur transmise au paramètre state de la méthode appelée utilisant le délégué.
Ce paramètre étant de type object permet de transmettre toute sorte de valeurs : objets, valeurs numériques (grâce à l'auto-boxing), tableaux de valeurs, ...

## Les événements

Un événement (event en anglais) est déclenché en dehors de l'application, par l'utilisateur (frappe au clavier, clic d'un bouton de souris, ...), par le système (connexion réseau, ...), par une autre application.

### Gestion par délégué

Les délégués sont utilisés pour gérer les événements. Toutefois, cela pose un problème si on utilise un délégué public dans une classe :
Le code utilisant cette classe peut être le suivant :
Les trois principaux problèmes sont les suivants :
* Si l'objet est partagé par plusieurs classes, fonctions, threads ou avec le système (comme c'est le cas pour les composants de l'interface graphique), plusieurs fonctions pourraient déjà avoir été associées au délégué PageRecue, et pourraient être supprimées du délégué par une simple affectation,
* L'ajout et le retrait de fonctions au délégué n'est pas thread-safe,
* L'appel au delegate ne devrait pas être possible en dehors de la classe ConnectionHttp.

### Solution : event

Les trois problèmes cités précédemment sont résolus par le mot clé event :
Ce mot clé protège l'accès au délégué de la manière suivante :
* Il n'est plus possible d'utiliser l'affection seule (opérateur =), il faut utiliser += ou -= ;
* L'ajout et le retrait sont réalisés de manière synchrone,
* Il n'est pas possible d'appeler le delegate en dehors de la classe où l'event est déclaré.

### Fonctionnement interne

La protection est réalisée de la manière suivante :
* Le véritable membre délégué est privé (même si l'event est public) ;
* L'utilisation des opérateurs += et -= est réalisée par des appels aux accesseurs add et remove de l'event.
Il est possible de remplacer les accesseurs par défaut créés par le compilateur. Pour l'exemple précédent, les accesseurs par défaut sont définis ainsi :

### Les événements du framework .Net

Les événements sont principalement utilisés dans le framework .Net pour les interfaces graphiques. Le délégué correspondant ne retourne rien (void) et possède deux paramètres : un objet indiquant la source de l'événement (le contrôle), et un objet du type nom_événementEventArgs dérivant de la classe EventArgs, contenant d'autres informations sur l'événement.