为什么"这个"指向类而不是类对象?

时间:2015-03-25 09:08:16

标签: c# winforms class events this

假设我有2个WinForms:Form1类的f1和Form2类的f2。我想要做的是:通过单击f1上的button1,应用程序将配置f1并运行f2。这是代码:

//Form1
public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent;
  }
  public delegate void EH_ChangeForm(object sender, EventArgs e);
  //this defines an event
  public static event EH_ChangeForm ChangeForm;
  private void button1_Click(object sender, EventArgs e)
  {
    //this raises the event
    ChangeForm(this, new EventArgs()); //  NRC happens here!!! Zzz~
  }
}

//Program
static class Program
{
  static Form1 f1;
  static Form2 f2;

  [STAThread]
  static void Main()
  {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    f1 = new Form1();
    f2 = new Form2();
    Application.Run(f1);
    //this subscribers to the event
    Form1.ChangeForm += Form1_ChangeForm;
  }

  static void Form1_ChangeForm(object sender, EventArgs e)
  {
    f1.Dispose();
    Application.Run(f2);
  }

}

问题 是:点击button1,程序在尝试引发事件时变得很糟糕(第34行; ChangeForm(这个,新的EventArgs()) ;&#34)。发生NullReferenceException,"这个"指向Form1而不是f1。

更一般地 ,我应该如何在课程中使用事件?即,一个类对象应该如何订阅另一个类对象引发的事件?

1 个答案:

答案 0 :(得分:0)

获得NullReferenceException的原因是因为没有向Form1.ChangeForm注册事件处理程序,因为Application.Run等待实例f1停止接收消息。

您需要在Main方法中交换两行,如下所示:

 Form1.ChangeForm += Form1_ChangeForm;
 Application.Run(f1);

始终尽可能快地注册事件处理程序""这样你就不会执行某些事情,并期望在没有人听的时候进行事件。

此外,在编写事件调用程序时,尝试使用缓存事件的模式然后调用它

private void FireChangeForm() {
    var handler = ChangeForm;
    if (handler != null) {
        handler(this, new EventArgs());
    }
}

所以你也要避免任何竞争条件。请阅读Eric Lippert撰写的关于您为什么要这样做的博客文章Events and Races