初始化事件操作以引发事件通知

时间:2019-05-10 08:06:36

标签: c#

我想创建事件操作以在发生某些事情时通知其他类。所以我当前的流程看起来像这样

enter image description here

出于测试目的,我创建了此代码

Program.cs

实例化第一个类并从中调用一个方法(构造函数可以)。

internal class Program
{
    private static void Main(string[] args)
    {
        First f = new First();
    }
}

First.cs

实例化第二个类并从中调用一个方法(构造函数很好)。当某些数据已更改时,侦听第二类的事件。

internal class First
{
    public First()
    {
        // ...

        Second s = new Second();
        s.Updated += OnSecondUpdated;
    }

    private void OnSecondUpdated()
    {
        Console.WriteLine("Done");
        Console.ReadLine();
    }
}

Second.cs

实例化第三个类并从中调用一个方法(构造函数很好)。在某些数据发生更改时侦听第三类事件并提出自己的数据。

internal class Second
{
    public event Action Updated;

    public Second()
    {
        // ...

        Third t = new Third();
        t.Updated += OnThirdUpdated;
    }

    private void OnThirdUpdated()
    {
        // ...

        Updated();
    }
}

Third.cs 更改某些数据后引发事件。

internal class Third
{
    public event Action Updated;

    public Third()
    {
        // ...

        Updated();
    }
}

不幸的是,事件变量为null。如何正确实例化这些变量?

2 个答案:

答案 0 :(得分:2)

这里的问题是,您正在尝试在构造函数中执行此操作,此时构造函数尚未Updated分配任何东西。您可以通过检查null来“解决”此问题:

internal class Third
{
    public event Action Updated;

    public Third()
    {
        // ...
        if(Updated != null)
            Updated();
    }
}

但这并不意味着您的代码现在就可以“正常工作”,因为您只在调用构造函数之后才为事件分配处理程序

Third t = new Third();
t.Updated += OnThirdUpdated;

因此,此模式的一种可能解决方案是不要在构造函数中进行事件的引发,而是将逻辑延迟到另一种方法。

internal class Third
{
    public event Action Updated;

    public Third()
    {            
    }

    public void Init()
    {
        // ...
        if(Updated != null)
            Updated();
    }
}

Third t = new Third();
t.Updated += OnThirdUpdated;
t.Init();

答案 1 :(得分:2)

由于基础对象的构造函数首先被调用,因此您可以在类可以预订事件之前调用Update()。我对其进行了更改,以便构造函数采用相关类并订阅事件本身。

internal class First
{
    public First()
    {
        Second s = new Second(this);
    }

    internal void OnSecondUpdated()
    {
        Console.WriteLine("Done");
        Console.ReadLine();
    }
}

internal class Second
{
    public event Action Updated;

    public Second(First f)
    {
        Updated += f.OnSecondUpdated;
        Third t = new Third(this);
    }

    internal void OnThirdUpdated()
    {
        Updated();
    }
}

internal class Third
{
    public event Action Updated;

    public Third(Second s)
    {
        Updated += s.OnThirdUpdated;
        Updated();
    }
}