事件处理程序中的延迟初始化

时间:2014-01-06 13:20:43

标签: c# event-handling lazy-initialization

我想知道如何“懒惰”从事件处理程序实例化对象

如果我有一个WinForms应用程序和两个按钮,例如:

public partial class Form1 : Form
{
    //MyClass obj = new MyClass();

    MyClass obj;

    public Form1()
    {
        InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)
    {
        obj = new MyClass();
        obj.StartWork();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        obj.StopWork();
    }
}

由于在用户单击button1之前我们不需要访问MyClass的成员,因此仅在该事件处理程序中实例化该类是有意义的。但是,单击第二个按钮将抛出空引用异常,因为该范围中的obj变量不引用任何内容。

2 个答案:

答案 0 :(得分:4)

您可以使用Lazy<T>

public partial class Form1 : Form
{
    Lazy<MyClass> obj = new Lazy<MyClass>();

    public Form1()
    {
        InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)
    {
        obj.Value.StartWork();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        obj.Value.StopWork();
    }
}

访问其Value属性将强制创建对象。

您还可以为Lazy构造函数提供自定义初始化函数。

答案 1 :(得分:1)

这应该可以阻止异常:

private void button2_Click(object sender, EventArgs e)
{
    // You need to make sure that obj is not null when this button is clicked.
    // One way is to disable this button until button1 is pressed. 
    // Or you can add this if statement.
    if(obj != null)
    {
        obj.StopWork();
    }
}

但你的陈述

  

因为该范围内的obj变量没有引用任何内容

错了。您可以通过obj课程中的所有方法访问Form1。因此,当您首先点击button1时,您会实例化类变量 obj,这可以在您班级的任何位置使用。但是,如果用户首先点击if(obj != null),则需要添加button2