我目前正在使用Visual Studio在C#中创建一个应用程序。我想创建一些代码,以便当变量的值为1时,执行某段代码。 我知道我可以使用if语句,但问题是该值将在异步进程中更改,因此从技术上讲,if语句可以在值更改之前被忽略。
是否可以创建事件处理程序,以便在变量值更改时触发事件?如果是这样,我该怎么做?
完全有可能我误解了if语句是如何工作的!任何帮助将不胜感激。
答案 0 :(得分:104)
对我而言似乎想要创建一个属性。
public int MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
if (_myProperty == 1)
{
// DO SOMETHING HERE
}
}
}
private int _myProperty;
这允许您在属性值更改时运行一些代码。如果你愿意的话,你可以在这里举办活动。
答案 1 :(得分:55)
只要字段的值发生变化,您就可以使用属性设置器来引发事件。
您可以拥有自己的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();
}
}
这种方法的优点是,如果需要,您可以让任何其他想要从您的类继承的类更改行为。
如果要捕获正在引发的其他线程中的事件,则必须注意不要更改在另一个线程中定义的对象的状态,这将导致抛出跨线程异常。要避免这种情况,您可以在要更改其状态的对象上使用Invoke方法,以确保更改发生在事件已引发的同一个线程中,或者您正在处理Windows窗体时可以使用BackgourndWorker在并行线程中做很好的事情。
答案 2 :(得分:39)
.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
}
}
}
希望这有用:)
答案 3 :(得分:9)
只使用属性
int _theVariable;
public int TheVariable{
get{return _theVariable;}
set{
_theVariable = value;
if ( _theVariable == 1){
//Do stuff here.
}
}
}
答案 4 :(得分:1)
您可以使用通用类:
class Wrapped<T> {
private T _value;
public Action ValueChanged;
public T Value
{
get => _value;
set
{
OnValueChanged();
_value = value;
}
}
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!
答案 5 :(得分:1)
一种简单的方法涉及对变量使用get和set函数
using System;
public string Name{
get{
return name;
}
set{
name= value;
OnVarChange?.Invoke();
}
}
private string name;
public event System.Action OnVarChange;