<分区>
我需要一个非常简单的例子来了解我自己对事件的了解。我觉得很难理解互联网或书籍中的例子。
<分区>
我需要一个非常简单的例子来了解我自己对事件的了解。我觉得很难理解互联网或书籍中的例子。
最佳答案
这是公开事件的类的简单实现。
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);
}
}
}
}
这个类可以像下面这样使用:
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.
}
关于控制流,执行流向SomeMethod()
。我们创建一个新的 ChangeNotifier
并调用它的构造函数。这会将 10
的值分配给私有(private) num
成员。
然后我们使用 +=
语法订阅事件。此运算符在右侧获取一个委托(delegate)(在我们的示例中,该委托(delegate)是一个 lambda)并将其添加到事件的委托(delegate)集合中。此操作不执行我们在 ChangeNotifier
中编写的任何代码。如果您愿意,可以通过事件的 add
和 remove
方法对其进行自定义,但很少需要这样做。
然后我们对 Number
属性执行几个简单的操作。首先,我们分配 10
,它在 Number
属性上运行 set
方法,value = 10
。但是 num
成员的值已经是 10
,因此初始条件的计算结果为 false,没有任何反应。
然后我们对 20
做同样的事情。这次值不同,所以我们将新值分配给 num
并触发事件。首先我们验证事件不为空。如果没有人订阅它,它就是 null。如果它不为 null(即,如果 订阅了它),我们将使用标准方法/委托(delegate)语法触发它。我们只需用事件的参数调用事件。这将调用已订阅该事件的所有方法,包括我们将执行 Console.WriteLine()
的 lambda。
如果一个线程可以在 Number
的 setter 中,而另一个线程正在取消订阅监听器,Henrik 已经成功地挑剔了存在的潜在竞争条件。对于还不了解事件如何运作的人,我认为这不是常见情况,但如果您担心这种可能性,请修改以下行:
if (this.NumberChanged != null)
this.NumberChanged(this, EventArgs.Empty);
变成这样:
var tmp = this.NumberChanged;
if (tmp != null)
tmp(this, EventArgs.Empty);
关于c# - c#.net 中委托(delegate)事件的 super 简单示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1782793/