Comment un EventHandler sait-il que seul l'opérateur = doit être autorisé à définir une classe?

StackOverflow https://stackoverflow.com/questions/813763

  •  03-07-2019
  •  | 
  •  

Question

J'ai commencé avec une question et en tapant la question, j'ai trouvé la réponse, mais au lieu de supprimer, j'ai pensé qu'il pourrait être utile de A) obtenir une confirmation et B) d'aider les autres.

Si j'ai un événement et que plusieurs endroits de l'application ajoutent des écouteurs, quel est le meilleur moyen de supprimer tous les écouteurs à la fois? Par exemple, je peux ...

myPage.OnPageOpened += OpenPage;

et plus tard dans mon code ...

myPage.OnPageOpened -= OpenPage;

Mais que se passe-t-il si j'ai des abonnés tiers inconnus et que je souhaite appuyer sur un bouton magique de réinitialisation qui efface tout et repart à zéro?

Vous pouvez utiliser les opérateurs + = et - = n'importe où contre EventHandler, car les surcharges d'opérateurs sont publiques. L'opérateur = surchargé est privé, il ne peut être appelé que dans la classe de définition.

Donc, dans la classe de définition, je peux l'utiliser pour effacer mon gestionnaire d'événements.

OnPageOpened = null;

Et pour exposer cette fonctionnalité, je pourrais ...

public void ClearPageOpenedEvents() {
   OnPageOpened = null;
}

Est-ce correct?

Était-ce utile?

La solution

Oui, vous avez raison. La raison en est que le compilateur crée un objet privé delegate sous les couvertures, comme ceci:

private EventHandler pageOpened;

public EventHandler PageOpened
{
    add { pageOpened += value; }
    remove { pageOpened -= value; }
}

Dans votre classe, vous avez une référence à l'instance privée delegate , c'est pourquoi vous pouvez effectuer l'affectation. Vous voulez vraiment exposer une méthode pour effacer les cibles si c'est la fonctionnalité dont vous avez besoin; vous ne voulez pas exposer le délégué lui-même.

Autres conseils

C'est la façon de le faire, mais comment quelque chose en dehors de la classe peut-il savoir que la classe doit abandonner tous ses écouteurs d'événements? Que se passe-t-il si une personne qui étend / utilise votre code attend cet événement de manière continue?

Vous pouvez utiliser l'opérateur d'affectation pour un événement, car c'est ainsi que fonctionnent l'ajout et la suppression d'événements. L’utilisation de Reflector éclaire bien la façon dont les événements se déroulent en C #.

Étant donné la classe simple de

public class MyClass
{
  public event EventHandler MyEvent;
}

Le code suivant est généré lors de la compilation

public class MyClass
{
  private EventHandler MyEvent;

  public event EventHandler MyEvent;
}

Ainsi, lorsque vous faites référence à MyEvent , vous faites référence à la variable de délégation privée MyEvent . Les opérateurs + = et - = sont "spéciaux". (car ils ne sont pas des opérateurs) et sont transformés en appelant les méthodes add et remove créées pour l'événement (qui utilisent elles-mêmes l'opérateur d'affectation).

[MethodImpl(MethodImplOptions.Synchronized)]
public void add_MyEvent(EventHandler value)
{
  this.MyEvent = (EventHandler) Delegate.Combine(this.MyEvent, value);
}

[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_MyEvent(EventHandler value)
{
    this.MyEvent = (EventHandler) Delegate.Remove(this.MyEvent, value);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top