web-dev-qa-db-fra.com

-event- ne peut apparaître que sur le côté gauche de + = ou - =

J'ai un événement en boucle. J'essaie d'empêcher la même méthode d'être ajoutée à un événement plus d'une fois. J'ai implémenté les accesseurs add et remove.

Cependant, j'obtiens une erreur indiquant que:

ItemsProcessed can only appear on the left hand side of += or -=

Quand j'essaye de les appeler, même dans la même classe.

ItemsProcessed(this, new EventArgs()); // Produces error

public event EventHandler ItemsProcessed
{
    add
    {
        ItemsProcessed -= value;
        ItemsProcessed += value;
    }
    remove
    {
        ItemsProcessed -= value;
    }
}
33
user76071

Avec un événement explicite, vous devez fournir votre propre magasin de support - soit un champ délégué, soit quelque chose comme EventHandlerList. Le code actuel est récursif. Essayer:

private EventHandler itemsProcessed;
public event EventHandler ItemsProcessed
{
    add
    {
        itemsProcessed-= value;
        itemsProcessed+= value;
    }

    remove
    {
        itemsProcessed-= value;
    }
}

Puis (et notant que je suis un petit prudent au sujet du "sur le point de tourner null" Edge-case re threading):

var snapshot = itemsProcessed;
if(snapshot != null) snapshot(this, EventArgs.Empty);

Avec les versions C # plus récentes, cela peut être simplifié:

itemsProcessed?.Invoke(this, EventArgs.Empty);
29
Marc Gravell

Il semble que si vous implémentez le EventHandler explicitement, vous ne pouvez pas vous référer à la "propriété" lors du déclenchement de l'événement. Vous devez vous référer au magasin de support.

9
John Robertson

Je ne peux pas dire à partir de votre message si vous essayez de déclencher l'événement à partir d'une classe dérivée ou non, mais une chose que j'ai trouvée est que vous ne pouvez pas définir un événement dans une classe de base, puis le déclencher (directement) dans une classe dérivée, pour une raison qui n'est pas encore très claire pour moi.

Je définis donc des fonctions protégées dans les classes de base pour déclencher des événements (qui sont définis dans ces classes de base), comme ceci:

// The signature for a handler of the ProgressStarted event.
// title: The title/label for a progress dialog/bar.
// total: The max progress value.
public delegate void ProgressStartedType(string title, int total);

// Raised when progress on a potentially long running process is started.
public event ProgressStartedType ProgressStarted;

// Used from derived classes to raise ProgressStarted.
protected void RaiseProgressStarted(string title, int total) {
    if (ProgressStarted != null) ProgressStarted(title, total);
}

Ensuite, dans la classe dérivée, j'appelle RaiseProgressStarted (title, total) au lieu d'appeler ProgressStarted (title, total).

Cela semble être un peu long. Peut-être que quelqu'un d'autre connaît un meilleur moyen de contourner ce problème.

8
Shavais

Quelle erreur? Je suppose que son erreur de débordement de pile, car vous appelez ajouter et supprimer sur votreserlf (même événement). Vous ne pouvez pas non plus déclencher l'événement ACCESSOR.

La manière valide de le faire est de créer un événement privé de support, qui sera ajouté et supprimé de l'accesseur public, et vous devez déclencher cet événement privé.

Dang, une minute de retard.

2
Euphoric