SetValue在这个特定事件中做什么

本文关键字:事件 什么 SetValue | 更新日期: 2023-09-27 17:59:27

我是事件的新手,我正在尝试了解事件是如何工作的,以及它们的用途。下面的代码是一个朋友帮我在网上找到的一些代码。它是有效的,但我不确定该事件是如何使用的。

在Main方法中有一个EventTest,它创建了一个新的对象e,然后用不同的参数两次调用SetValue方法。

static void Main(string[] args)
{
    EventTest e = new EventTest(5);
    e.SetValue(7);
    e.SetValue(11);
    Console.ReadKey();
}

下面的代码实际上就是事件代码。OnNumChanged是在号码更改时写入信息的事件。因此,当SetValue(100)设置为不同的数字时,就会触发事件。

问题:当SetValue设置为新值时,这是导致事件更改正确的原因

我对事件变化还不够熟悉,我真的可以用一些好的例子,或者让别人一行一行地解释这个例子。

e.SetValue(7);
e.SetValue(11);
protected virtual void OnNumChanged()
{
     if (ChangeNum != null)
     {
          ChangeNum();
     }
     else
     {
          Console.WriteLine("Event fired!");
     }
}

代码:

class Program
{
    static void Main(string[] args)
    {
        EventTest e = new EventTest(5);
        e.SetValue(7);
        e.SetValue(11);
        Console.ReadKey();
    }
}
public class EventTest
{
    private int          value;
    public delegate void NumManipulationHandler();
    public event         NumManipulationHandler ChangeNum;
    public EventTest(int n)
    {
        SetValue(n);
    }
    public void SetValue(int n)
    {
        if (value != n)
        {
            value = n;
            OnNumChanged();
        }
    }
    protected virtual void OnNumChanged()
    {
        if (ChangeNum != null)
        {
            ChangeNum();
        }
        else
        {
            Console.WriteLine("Event fired!");
        }
    }
}

SetValue在这个特定事件中做什么

是的,您是正确的:

public void SetValue(int n)
{
    if (value != n) // check if the value actually changed
    {
        value = n;
        OnNumChanged(); // call the event "in a save way", see below
    }
}
protected virtual void OnNumChanged()
{
    if (ChangeNum != null) // check if someone is listening - PROBLEM: see below
        ChangeNum(); // trigger the event and call all event handlers registered
}

我上面提到的问题是:让事件检查null,然后再次执行。在多线程环境中,这可能会发生,在这两个"得到"之间,它会发生变化=>创建本地副本:

protected virtual void OnNumChanged()
{
    var changeNum = ChangeNum;
    if (changeNum != null)
        changeNum();
}

要真正获得事件通知,您需要注册该事件,例如:

static void Main(string[] args)
{
    EventTest e = new EventTest(5);
    e.ChangeNum += () => Console.WriteLine("Num changed"); //<== this
    e.SetValue(7);
    e.SetValue(11);
    Console.ReadKey();
}

在活动中提供新的价值也更有意义。这可以通过将委托更改为:来实现

public delegate void NumManipulationHandler(int newValue);

并称之为:

ChangeNum(value);

然后你可以像一样注册

e.ChangeNum += newValue => Console.WriteLine("Num changed to " + newValue);

简而言之:是的!如果与SetValue方法一起传递的值与已经存储的值不同,则会触发一个事件,指示更改。

任何其他可能订阅此类事件的代码都可以以任何方式做出相应的反应。

尽管我自己可以从视频中更容易地学习(我建议你也在C#中搜索事件的视频),但这一切都归结为当对象发生一些有趣的事情时,类向该类的客户端提供通知的一种方式(进一步阅读此处)