C# 在C中使用事件处理程序#
我试图观察c#中的一个值,并在它发生变化时触发一个函数。根据阅读的例子,我有: //事件观察者C# 在C中使用事件处理程序#,c#,eventhandler,C#,Eventhandler,我试图观察c#中的一个值,并在它发生变化时触发一个函数。根据阅读的例子,我有: //事件观察者 private int _currentFrame =1; public event System.EventHandler FrameChanged; protected virtual void OnFrameChanged() { if (FrameChanged != null) FrameChanged(this, EventArgs.Empty); } public int A
private int _currentFrame =1;
public event System.EventHandler FrameChanged;
protected virtual void OnFrameChanged()
{
if (FrameChanged != null) FrameChanged(this, EventArgs.Empty);
}
public int Age
{
get
{
return _currentFrame;
}
set
{
//#3
_currentFrame = value;
OnFrameChanged();
}
}
在我的主要职责中:
_currentFrame += _currentFrame;
据我所知,这应该会触发事件观察器,但事实并非如此。我错过了什么
谢谢。您尚未为FrameChanged分配任何事件
yourInstance.FrameChanged+= () => DoSomething();
要调用事件处理程序,需要做两件事
someObject.FrameChanged += SomeObjectFrameChanged;
...
private void SomeObjectFrameChanged(object sender, EventArgs e)
{
... code here
}
set
{
if (_currentFrame == value) return;
//#3
_currentFrame = value;
OnFrameChanged();
}
第二个在表面上看起来不错,属性调用OnFrameChanged
yourInstance.FrameChanged+= () => DoSomething();
顺便说一下,OnFrameChanged不是实现事件处理程序激发方法的推荐方法,您应该使用以下模板:
protected virtual void OnFrameChanged()
{
var evt = FrameChanged;
if (evt != null) evt(this, EventArgs.Empty);
}
此更改(将事件值提升为局部变量)的原因是,如果您处于多线程环境中,在检查事件是否至少有一个事件处理程序(!=null
)后,另一个线程可能会取消订阅最后一个事件处理程序。吹毛求疵,但你还是应该改变它
在C#6中,您可以将上述方法更改为:
protected virtual void OnFrameChanged()
{
FrameChanged?.Invoke(this, EventArgs.Empty);
}
因为这会做同样的事情
但现在我们来看看您的代码和期望中的真正缺陷:
_currentFrame += _currentFrame;
您希望这会触发您的事件,但这是错误的
您直接访问backing字段,它绕过属性中的所有代码,因此这里没有调用OnFrameChanged
的代码,因此不会触发事件
相反,您应该访问该属性:
次要的吹毛求疵#2是您应该确保只有在属性实际发生更改时才触发
PropertyChanged
:
Age = 1;
Age = 1; // did not change, do not fire PropertyChanged
因此,您应该实现如下属性设置器:
someObject.FrameChanged += SomeObjectFrameChanged;
...
private void SomeObjectFrameChanged(object sender, EventArgs e)
{
... code here
}
set
{
if (_currentFrame == value) return;
//#3
_currentFrame = value;
OnFrameChanged();
}
…+=(发送方,e)=>DoSomething()代码>如果事件处理程序直接更改支持字段,则不会触发。谢谢!这是有道理的。为什么它要触发事件处理程序?您不是在更改属性,而是在更改支持字段。没有对备份字段的监控,您只有属性中的代码。因此,请尝试Age+=Age
或Age++
。谢谢!正是我需要的解释。