这是一个公开事件的类的简单实现.
public class ChangeNotifier
{
// Local data
private int num;
// Ctor to assign data
public ChangeNotifier(int number) { this.num = number; }
// The event that can be subscribed to
public event EventHandler NumberChanged;
public int Number
{
get { return this.num; }
set
{
// If the value has changed...
if (this.num != value)
{
// Assign the new value to private storage
this.num = value;
// And raise the event
if (this.NumberChanged != null)
this.NumberChanged(this, EventArgs.Empty);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个类可以使用如下所示:
public void SomeMethod()
{
ChangeNotifier notifier = new ChangeNotifier(10);
// Subscribe to the event and output the number when it fires.
notifier.NumberChanged += (s, e) => Console.Writeline(notifier.Number.ToString());
notifier.Number = 10; // Does nothing, this is the same value
notifier.Number = 20; // Outputs "20" because the event is raised and the lambda runs.
}
Run Code Online (Sandbox Code Playgroud)
关于控制流程,执行流入SomeMethod()
.我们创建一个new ChangeNotifier
,从而调用它的构造函数.这会将值分配给10
私有num
成员.
然后我们使用+=
语法订阅该事件.此运算符在右侧接受委托(在我们的示例中,该委托是lambda)并将其添加到事件的委托集合中.此操作不会执行我们在其中编写的任何代码ChangeNotifier
.如果您愿意,可以通过事件add
和remove
方法对其进行自定义,但很少需要这样做.
然后我们在Number
属性上执行几个简单的操作.首先我们分配10
,set
在Number
属性上运行方法value = 10
.但是该num
成员已经被重视10
,因此初始条件评估为false并且没有任何反应.
然后我们做同样的事情20
.这次值不同,因此我们将新值赋给num
并触发事件.首先,我们验证事件不是null.如果没有订阅它,它就为null.如果它不是空(即,如果事情被预订的话),我们使用标准方法/委托语法火了.我们只需使用事件的参数调用事件.这将调用已订阅事件的所有方法,包括将执行a的lambda Console.WriteLine()
.
Henrik已经成功地挑选了存在的潜在竞争条件,如果一个线程可以在其中,Number
而另一个线程取消订阅一个侦听器.对于那些还不了解事件如何工作的人来说,我不认为这是一个常见的情况,但是如果你担心这种可能性,请修改以下几行:
if (this.NumberChanged != null)
this.NumberChanged(this, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)
是这样的:
var tmp = this.NumberChanged;
if (tmp != null)
tmp(this, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10258 次 |
最近记录: |