[英]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 委托。
通常有一个模式:
这是一个例子
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.