127 votes

"La soustraction de délégué a un résultat imprévisible" dans ReSharper/C# ?

Lorsque vous utilisez myDelegate -= eventHandler Problèmes liés à ReSharper (version 6) :

La soustraction des délégués a un résultat imprévisible

Le raisonnement derrière tout cela est le suivant expliqué par JetBrains ici . L'explication a du sens et, après l'avoir lue, je doute de toutes mes utilisations de - sur les délégués.

Comment alors ,

  • Puis-je écrire un événement non automatique sans rendre ReSharper grincheux ?
  • ou existe-t-il une meilleure façon et/ou une façon "correcte" de mettre en œuvre ce système ?
  • ou, puis-je simplement ignorer ReSharper ?

Voici un code simplifié :

public delegate void MyHandler (object sender);

MyHandler _myEvent;

public event MyHandler MyEvent
{
    add
    {
        _myEvent += value;
        DoSomethingElse();
    }
    remove
    {
        _myEvent -= value; // <-- ReSharper warning here
    }
}

139voto

Allon Guralnek Points 8545

N'ayez pas peur ! La première partie de l'avertissement de ReSharper ne s'applique qu'à la suppression de listes de délégués. Dans votre code, vous supprimez toujours un seul délégué. La deuxième partie parle de l'ordre des délégués après qu'un délégué en double ait été supprimé. Un événement ne garantit pas un ordre d'exécution pour ses abonnés, donc cela ne vous concerne pas vraiment non plus.

Étant donné que le mécanisme ci-dessus peut conduire à des résultats imprévisibles, ReSharper émet un avertissement chaque fois qu'il rencontre un opérateur de soustraction de délégué.

ReSharper émet cet avertissement parce que la soustraction de délégués de multidiffusion peut avoir des écueils, il ne condamne pas entièrement cette fonctionnalité du langage. Heureusement, ces problèmes sont des cas marginaux et il est peu probable que vous les rencontriez si vous ne faites qu'instrumenter des événements simples. Il n'y a pas de meilleure façon d'implémenter votre propre add / remove les manipulateurs, vous devez juste faire attention.

Je suggère de rétrograder le niveau d'avertissement de ReSharper pour ce message à "Hint" afin de ne pas vous désensibiliser à leurs avertissements, qui sont généralement utiles.

30voto

blimac Points 319

Vous ne devez pas utiliser directement les délégués pour additionner ou soustraire. Au lieu de cela, votre champ

MyHandler _myEvent;

Il devrait plutôt être déclaré comme un événement également. Cela résoudra le problème sans mettre en péril votre solution et en conservant l'avantage de l'utilisation des événements.

event MyHandler _myEvent;

L'utilisation de la somme ou de la soustraction de délégués est dangereuse car vous pouvez perdre des événements en assignant 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é Multicast comme lorsqu'il est déclaré comme un événement). Pour illustrer, si la propriété mentionnée dans cette question n'a pas été signalée comme un événement, le code ci-dessous fera en sorte que les deux premières affectations soient PERDUES, parce que quelqu'un a simplement assigné au délégué (ce qui est également valide !).

myObject.MyEvent += Method1; 
myObject.MyEvent += Method2;
myObject.MyEvent = Method3;

Lors de l'affectation de la méthode 3, j'ai complètement perdu les deux abonnements initiaux. L'utilisation des événements évitera ce problème et supprimera en même temps l'avertissement de ReSharper.

-17voto

Lui donner la valeur = null au lieu d'utiliser -=

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X