C# 为什么;这";指向类而不是类对象?
假设我有两个WinForms:Form1类的f1和Form2类的f2。我想做的是:通过单击f1上的按钮1,应用程序将处理f1并运行f2。代码如下:C# 为什么;这";指向类而不是类对象?,c#,winforms,class,events,this,C#,Winforms,Class,Events,This,假设我有两个WinForms:Form1类的f1和Form2类的f2。我想做的是:通过单击f1上的按钮1,应用程序将处理f1并运行f2。代码如下: //Form1 public partial class Form1 : Form { public Form1() { InitializeComponent; } public delegate void EH_ChangeForm(object sender, EventArgs e); //this defines
//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
更一般地说,我应该如何在类之间使用事件?i、 例如,一个类对象应该如何订阅由另一个类对象引发的事件?您得到
NullReferenceException
的原因是没有事件处理程序注册到您的Form1.ChangeForm
,因为Application.Run等待实例f1停止接收消息
您需要交换Main方法中的两行,如下所示:
Form1.ChangeForm += Form1_ChangeForm;
Application.Run(f1);
始终尝试“尽可能快地”注册事件处理程序,这样您就不会执行某些操作,也不会期望在无人侦听时执行事件
此外,在编写事件invocators时,请尝试使用缓存事件然后调用它的模式
private void FireChangeForm() {
var handler = ChangeForm;
if (handler != null) {
handler(this, new EventArgs());
}
}
所以你也要避免任何比赛条件。请阅读Eric Lippert的博客文章,了解您为什么要这样做。您根本不需要担心如何处理,也不应该使用
应用程序。运行打开表单,有Show
和ShowDialog
可以这样做。不清楚您所说的“this”指的是表单1,而不是f1。“还不清楚为什么您选择创建自己的委托类型,其签名与EventHandler
…完全相同,
此
表示当前实例。如果不将局部类与静态类、静态事件和显式随机处理混合在一起,所有这些都将更容易调试。是什么导致了NRE?@Jon Skeet:我想传输的是一个对象,但“this”指向类,而不是对象。这个程序只是一个测试,为了简单起见,我没有定义任何特殊的委托。它可以工作。多谢各位@帕特里克:谢谢你的解释,我真的很感激!