c#.net中Delegate-Event的超级简单示例?

Bab*_*abu 4 .net c# c#-3.0

我需要一个非常简单的例子来了解事件.我感觉很难理解互联网或书籍中的例子.

Gre*_*g D 6

这是一个公开事件的类的简单实现.

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.如果您愿意,可以通过事件addremove方法对其进行自定义,但很少需要这样做.

然后我们在Number属性上执行几个简单的操作.首先我们分配10,setNumber属性上运行方法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)