Lors de l'utilisation de myDelegate -= eventHandler
problèmes ReSharper (version 6):
La soustraction de délégués a un résultat imprévisible
Le rationnel derrière cela est expliqué par JetBrains ici . L'explication a du sens et, après l'avoir lue, je doute de toutes mes utilisations des -
délégués.
Comment alors ,
- puis-je écrire un événement non automatique sans rendre ReSharper grincheux?
- ou, y a-t-il une manière meilleure et / ou «correcte» de mettre en œuvre cela?
- ou puis-je simplement ignorer ReSharper?
Voici le code simplifié:
public delegate void MyHandler (object sender);
MyHandler _myEvent;
public event MyHandler MyEvent
{
add
{
_myEvent += value;
DoSomethingElse();
}
remove
{
_myEvent -= value; // <-- ReSharper warning here
}
}
Réponses:
N'aie pas peur! La première partie de l'avertissement de ReSharper s'applique uniquement à la suppression de listes de délégués. Dans votre code, vous supprimez toujours un seul délégué. La deuxième partie traite de l'ordre des délégués après la suppression d'un délégué en double. Un événement ne garantit pas un ordre d'exécution pour ses abonnés, il ne vous affecte donc pas vraiment non plus.
ReSharper émet cet avertissement car la soustraction de délégués de multidiffusion peut avoir des pièges, il ne condamne pas entièrement cette fonctionnalité de langage. Heureusement, ces pièges sont dans des cas marginaux et il est peu probable que vous les rencontriez si vous instrumentez simplement des événements simples. Il n'y a pas de meilleure façon d'implémenter vos propres
add
/remove
handlers, vous devez juste en prendre note.Je suggérerais de déclasser le niveau d'avertissement de ReSharper pour ce message sur "Hint" afin que vous ne soyez pas insensible à leurs avertissements, qui sont généralement utiles.
la source
Delegate
ne pas surcharger+
et-
.)PIT OF SUCCESS IS THAT WAY --->
.Delegate.Combine
qui "aplatit" les délégués multicast, donc si on lui donne des délégués [X, Y] et Z, il ne peut pas dire si le résultat doit être [X, Y, Z] ou [[ X, Y], Z] (ce dernier délégué tient le[X,Y]
délégué comme sonTarget
, et laInvoke
méthode de ce délégué comme sonMethod
).Vous ne devez pas utiliser directement les délégués pour additionner ou soustraire. Au lieu de votre champ
Doit être également déclaré comme un événement. Cela résoudra le problème sans risquer votre solution et bénéficiera toujours de l'utilisation d'événements.
L'utilisation de la somme ou de la soustraction du délégué est dangereuse car vous pouvez perdre des événements en affectant simplement le délégué (selon la déclaration, le développeur ne déduira pas directement qu'il s'agit d'un délégué de multidiffusion comme lorsqu'il est déclaré comme un événement). Juste pour illustrer, si la propriété mentionnée sur cette question n'a pas été signalée comme un événement, le code ci-dessous mettra en cause les deux premières affectations comme PERDUES, car quelqu'un est simplement affecté au délégué (ce qui est également valide!).
Lors de l'attribution de Method3, j'ai complètement perdu les deux abonnements initiaux. L'utilisation d'événements évitera ce problème et supprimera en même temps l'avertissement ReSharper.
la source
définissez-le sur = null au lieu d'utiliser - =
la source
remove
méthode d'un événement ne doit pas supprimer tous les gestionnaires, mais plutôt le gestionnaire dont la suppression a été demandée.