Quelle est la bonne façon de se désabonner des événements en c #?

J’ai une classe modèle avec un événement auquel je souscris à d’autres classes. Je veux m’inscrire et me désabonner correctement dans chaque classe.

  • Premièrement, je veux garantir que dans MyClass, je ne désabonne qu’une seule fois, même si ce code existe en peu de méthodes.
  • Deuxièmement, il existe d’autres classes, à l’exception de MyClass, qui utilise OnMyEvent. Par conséquent, je ne souhaite pas annuler involontairement la non-inscription de l’événement de la classe.

    MyClass(IModel model) { _model = model; _model.OnMyEvent +=EventHandle; } Close() { _model.OnMyEvent -=EventHandle; } Disconnect() { //I want to check if OnMyEvent has already unsibscribed //Moreover OnMyEvent is used in other classes and //I don't want to mess up with it here _model.OnMyEvent -=EventHandle; } 

Si vous ne vous abonnez qu’une seule fois, peu importe le nombre de fois que vous vous désabonnez: désabonner sans abonnement est un no-op. De même, l’intérêt de l’API d’événement est qu’il est impossible de désabonner accidentellement d’autres abonnements (autres types ou autres instances du même type).

En tant que tel, le code affiché devrait être correct, bien que cela puisse valoir la peine de déplacer les deux appels vers une seule méthode qui gère cela. Cela pourrait être exagéré, cependant.

De plus, si votre type est IDisposable , assurez-vous qu’il est également appelé dans ce chemin de code (probablement en appelant Close() ).

Vous pouvez désinscrire en toute sécurité le même gestionnaire d’un événement plusieurs fois. Une vérification supplémentaire n’est pas nécessaire et serait contre-productive.

Si vous voulez vous garantir que vous vous désabonnez une seule fois, vous pouvez utiliser la méthode GetInvocationList :

 if (_model.OnMyEvent != null && _model.GetInvocationList().Contains(EventHandle)) { _model.OnMyEvent -= EventHandle } 

Mais comme mentionné par les autres, vous pouvez vous désabonner plusieurs fois. Si ce n’est pas vraiment un problème, continuez comme ça. La solution que je propose est simplement du code-noise. Désinscrire simplement sur une ligne est beaucoup plus simple et plus facile à lire lorsque votre classe commence à grandir.

Vous pouvez également contrôler les abonnements et les désinscriptions avec cette déclaration. Mais vous devez également parcourir le dictionnaire et appeler des delegates souscrits manuellement.

  private Dictionary TestEvents { get; } public event EventHandler TestEvent { add { ssortingng name = value.GetType().FullName; if (!TestEvents.ContainsKey(name)) { TestEvents.Add(name, value); } } remove { ssortingng name = value.GetType().FullName; if (TestEvents.ContainsKey(name)) { TestEvents.Remove(name); } } }