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

时间:2014-04-23 13:29:04

标签: c#

我是新手,我正在努力了解一个事件的运作方式以及它们的目的。下面的代码是我们在网上找到的朋友帮助我的一些代码。它有效,但我不确定如何使用该事件。

在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!");
        }
    }
}

2 个答案:

答案 0 :(得分:0)

是的,你是对的:

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);

答案 1 :(得分:0)

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

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

即使我自己可以从视频中学习更轻松(我建议您也可以在C#中搜索有关事件的视频),但这一切都归结为一种类向同类客户提供通知的方式当某个对象发生了一些有趣的事情时(进一步阅读here