为什么 "this" 指向 class 而不是 class 对象?
why "this" points to class rather than class object?
假设我有 2 个 WinForms:class Form1 的 f1 和 class 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);
}
}
问题 是:通过单击按钮 1,程序在尝试引发事件时变得糟糕(行 "ChangeForm(this, new EventArgs());" ).发生 NullReferenceException,"this" 指向 Form1 而不是 f1。
更一般地说,我应该如何使用 class 中的事件?即,class 对象应如何订阅另一个 class 对象引发的事件?
你得到 NullReferenceException
的原因是因为没有事件处理程序注册到你的 Form1.ChangeForm
,因为 Application.Run 等待实例 f1 停止接收消息。
您需要交换 Main 方法中的两行,如下所示:
Form1.ChangeForm += Form1_ChangeForm;
Application.Run(f1);
始终尝试注册事件处理程序"as fast as possible",这样您就不会执行某些操作并期望在没有人收听时执行某个事件。
此外,在编写事件调用器时,请尝试使用缓存事件然后调用它的模式
private void FireChangeForm() {
var handler = ChangeForm;
if (handler != null) {
handler(this, new EventArgs());
}
}
所以你也避免了任何竞争条件。请阅读 Eric Lippert 的博客 post Events and Races,了解您应该这样做的原因。
假设我有 2 个 WinForms:class Form1 的 f1 和 class 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);
}
}
问题 是:通过单击按钮 1,程序在尝试引发事件时变得糟糕(行 "ChangeForm(this, new EventArgs());" ).发生 NullReferenceException,"this" 指向 Form1 而不是 f1。
更一般地说,我应该如何使用 class 中的事件?即,class 对象应如何订阅另一个 class 对象引发的事件?
你得到 NullReferenceException
的原因是因为没有事件处理程序注册到你的 Form1.ChangeForm
,因为 Application.Run 等待实例 f1 停止接收消息。
您需要交换 Main 方法中的两行,如下所示:
Form1.ChangeForm += Form1_ChangeForm;
Application.Run(f1);
始终尝试注册事件处理程序"as fast as possible",这样您就不会执行某些操作并期望在没有人收听时执行某个事件。
此外,在编写事件调用器时,请尝试使用缓存事件然后调用它的模式
private void FireChangeForm() {
var handler = ChangeForm;
if (handler != null) {
handler(this, new EventArgs());
}
}
所以你也避免了任何竞争条件。请阅读 Eric Lippert 的博客 post Events and Races,了解您应该这样做的原因。