c# - c#.net 中委托(delegate)事件的 super 简单示例?

标签 c# .net c#-3.0

<分区>

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

最佳答案

这是公开事件的类的简单实现。

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 中编写的任何代码。如果您愿意,可以通过事件的 addremove 方法对其进行自定义,但很少需要这样做。

然后我们对 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/

相关文章:

c# - 将零件渲染到 Orchard CMS 中的不同区域

.net - .Net 2.0 的代码契约和防御性编程库?

.net - 使用反射 c# 映射业务对象和实体对象

c# - 记录对象的状态。获取其所有属性值作为字符串

c# - 使用 C# 通过 Windows 服务打印 PDF

c# - javascript按键按下问题

C# TCP client read occasionally receives no data - 'nothing'

c# - 使用 IDataErrorInfo 或任何类似的模式来传播错误消息

.net - 第三方 .NET 模块未在 "lm"命令的输出中列出

C# Xml 序列化和反序列化