web-dev-qa-db-fra.com

Comment déclencher un événement lorsque la valeur d'une variable est modifiée?

Je crée actuellement une application en C # à l'aide de Visual Studio. Je veux créer du code de sorte que lorsqu'une variable a une valeur de 1, un certain morceau de code est exécuté. Je sais que je peux utiliser une instruction if, mais le problème est que la valeur sera modifiée dans un processus asynchrone, donc techniquement, l'instruction if pourrait être ignorée avant que la valeur ne soit modifiée.

Est-il possible de créer un gestionnaire d'événements afin que, lorsque la valeur de la variable change, un événement soit déclenché? Si oui, comment puis-je faire cela?

Il est tout à fait possible que j'aie mal compris comment une déclaration if fonctionne! Toute aide serait très appréciée.

89
James Mundy

Il me semble que vous voulez créer une propriété.

public int MyProperty
{
    get { return _myProperty; }
    set
    {
        _myProperty = value;
        if (_myProperty == 1)
        {
            // DO SOMETHING HERE
        }
    }
}

private int _myProperty;

Cela vous permet d'exécuter du code chaque fois que la valeur de la propriété change. Vous pouvez organiser un événement ici, si vous le souhaitez.

112
Jonathan Wood

Vous pouvez utiliser un configurateur de propriétés pour déclencher un événement chaque fois que la valeur d'un champ va changer.

Vous pouvez avoir votre propre délégué EventHandler ou vous pouvez utiliser le célèbre délégué System.EventHandler.

Habituellement, il existe un modèle pour cela:

  1. Définissez un événement public avec un délégué de gestionnaire d'événement (qui a un argument de type EventArgs).
  2. Définissez une méthode virtuelle protégée appelée OnXXXXX (OnMyPropertyValueChanged par exemple). Dans cette méthode, vous devez vérifier si le délégué du gestionnaire d’événements est null et sinon, vous pouvez l’appeler (cela signifie qu’une ou plusieurs méthodes sont associées à la délégation d’événements).
  3. Appelez cette méthode protégée chaque fois que vous souhaitez informer les abonnés que quelque chose a changé.

Voici un exemple

private int _age;

//#1
public event System.EventHandler AgeChanged;

//#2
protected virtual void OnAgeChanged()
{ 
     if (AgeChanged != null) AgeChanged(this,EventArgs.Empty); 
}

public int Age
{
    get
    {
         return _age;
    }

    set
    {
         //#3
         _age=value;
         OnAgeChanged();
    }
 }

L'avantage de cette approche est que vous laissez toutes les autres classes qui souhaitent hériter de votre classe modifier le comportement si nécessaire.

Si vous souhaitez intercepter un événement dans un thread différent lors de son levée, veillez à ne pas modifier l'état des objets définis dans un autre thread, ce qui provoquerait la génération d'une exception. Pour éviter cela, vous pouvez utiliser une méthode Invoke sur l’objet dont vous souhaitez modifier l’état pour vous assurer que la modification a bien lieu dans le même thread que celui qui a été déclenché ou si vous utilisez un formulaire Windows. pouvez utiliser un BackgourndWorker pour faire les choses dans un fil parallèle Nice et facile.

58
Beatles1692

Le framework .NET fournit en fait une interface que vous pouvez utiliser pour notifier les abonnés quand une propriété a été modifiée: System.ComponentModel.INotifyPropertyChanged. Cette interface a un événement PropertyChanged. Il est généralement utilisé dans WPF pour la liaison, mais je l'ai trouvé utile dans les couches de gestion afin de normaliser la notification de modification de propriété.

En ce qui concerne la sécurité du fil, je mettrais un verrou sous le passeur afin que vous ne couriez pas dans des conditions de course.

Voici mes pensées en code :):

public class MyClass : INotifyPropertyChanged
{
    private object _lock;

    public int MyProperty
    {
        get
        {
            return _myProperty;
        }
        set
        {
            lock(_lock)
            {
                //The property changed event will get fired whenever
                //the value changes. The subscriber will do work if the value is
                //1. This way you can keep your business logic outside of the setter
                if(value != _myProperty)
                {
                    _myProperty = value;
                    NotifyPropertyChanged("MyProperty");
                }
            }
        }
    }

    private NotifyPropertyChanged(string propertyName)
    {
        //Raise PropertyChanged event
    }
    public event PropertyChangedEventHandler PropertyChanged;
}


public class MySubscriber
{
    private MyClass _myClass;        

    void PropertyChangedInMyClass(object sender, PropertyChangedEventArgs e)
    {
        switch(e.PropertyName)
        {
            case "MyProperty":
                DoWorkOnMyProperty(_myClass.MyProperty);
                break;
        }
    }

    void DoWorkOnMyProperty(int newValue)
    {
        if(newValue == 1)
        {
             //DO WORK HERE
        }
    }
}

J'espère que c'est utile :)

43
Daniel Sandberg

juste utiliser une propriété

int  _theVariable;
public int TheVariable{
  get{return _theVariable;}
  set{
    _theVariable = value; 
    if ( _theVariable == 1){
      //Do stuff here.
    }
  }
}
11
Russell Troywest