繁体   English   中英

当变量的值改变时如何触发事件?

[英]How to trigger event when a variable's value is changed?

我目前正在使用 Visual Studio 在 C# 中创建一个应用程序。 我想创建一些代码,以便当变量的值为 1 时执行某段代码。 我知道我可以使用 if 语句,但问题是该值将在异步过程中更改,因此从技术上讲,可以在值更改之前忽略 if 语句。

是否可以创建一个事件处理程序,以便在变量值更改时触发事件? 如果是这样,我该怎么做?

我完全有可能误解了 if 语句的工作原理。 任何帮助将非常感激。

在我看来,你想创建一个属性。

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

private int _myProperty;

这允许您在属性值更改时运行一些代码。 如果你愿意,你可以在这里发起一个活动。

每当字段的值发生变化时,您都可以使用属性设置器引发事件。

您可以拥有自己的 EventHandler 委托,也可以使用著名的 System.EventHandler 委托。

通常有一个模式:

  1. 使用事件处理程序委托(具有 EventArgs 类型的参数)定义公共事件。
  2. 定义一个名为 OnXXXXX 的受保护虚拟方法(例如 OnMyPropertyValueChanged)。 在此方法中,您应该检查事件处理程序委托是否为 null,如果不是,您可以调用它(这意味着事件委托附加了一个或多个方法)。
  3. 每当您想通知订阅者某些事情发生了变化时,请调用此受保护的方法。

这是一个例子

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();
    }
 }

这种方法的优点是您可以让任何其他想要从 class 继承的类在必要时更改行为。

如果您想在另一个线程中捕获一个正在引发的事件,您必须小心不要更改在另一个线程中定义的对象的 state,这将导致引发跨线程异常。 为避免这种情况,您可以在要更改其 state 的 object 上使用 Invoke 方法,以确保更改发生在引发事件的同一线程中,或者如果您正在处理 ZAEA23489CE3AA9B6406EBB2可以使用 BackgourndWorker 在并行线程中轻松轻松地做事。

.NET 框架实际上提供了一个接口,您可以使用该接口在属性发生更改时通知订阅者:System.ComponentModel.INotifyPropertyChanged。 此接口有一个事件 PropertyChanged。 它通常在 WPF 中用于绑定,但我发现它在业务层中作为一种标准化属性更改通知的方式很有用。

在线程安全方面,我会在设置器中加一个锁,这样你就不会遇到任何竞争条件。

这是我在代码中的想法:):

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
        }
    }
}

希望这会有所帮助:)

只使用一个属性

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

您可以使用通用 class:

class Wrapped<T>  {
    private T _value;

    public Action ValueChanged;

    public T Value
    {
        get => _value;

        set
        {
            if ( _value != value )
            {
                _value = value;
                OnValueChanged();
            }
        }
    }

    protected virtual void OnValueChanged() => ValueChanged?.Invoke() ;
}

并将能够执行以下操作:

var i = new Wrapped<int>();

i.ValueChanged += () => { Console.WriteLine("changed!"); };

i.Value = 10;
i.Value = 10;
i.Value = 10;
i.Value = 10;

Console.ReadKey();

结果:

changed!
changed!
changed!
changed!
changed!
changed!
changed!

一个简单的方法是对变量使用 get 和 set 函数


    using System;
    public string Name{
    get{
     return name;
    }
    
    set{
     name= value;
     OnVarChange?.Invoke();
    }
    }
    private string name;
    
    public event System.Action OnVarChange;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM