我正在创建一个类库,我在Windows窗体程序中使用它。 我想在程序中处理这个库的事件。 我正在使用此代码:
库内的类:
public class KSEDataServIO
{
public delegate void IsReadyForUseEventHandler(object sender, IsReadyForUseEventArgs e);
public event IsReadyForUseEventHandler IsReadyForUse;
public KSEDataServIO(){
EvArg = new IsReadyForUseEventArgs("AuthOkay");
IsReadyForUse(this, EvArg); //This is where i get the issue.
}
}
而且,在窗口中,我正在这样做:
private void button1_Click(object sender, EventArgs e) {
KSEDataServIO con = new KSEDataServIO();
con.IsReadyForUse += new KSEDataServIO.IsReadyForUseEventHandler(con_IsReadyForUse);
}
void con_IsReadyForUse(object sender, IsReadyForUseEventArgs e)
{
MessageBox.Show(e.Etat);
}
我对'IsReadyForUse(this,EvArg)行'有一个NullReferenceException;'在类库中。 有什么想法吗?
答案 0 :(得分:2)
您的问题是您在KSEDataServIO
的构造函数中引发了事件。在那时,没有订阅该事件处理程序,因此它引发了一个空引用异常。
因此,有一件事是正确地引发通常使用此模式的事件处理程序:
public delegate void IsReadyForUseEventHandler(object sender, IsReadyForUseEventArgs e);
public event IsReadyForUseEventHandler IsReadyForUse;
void OnIsReadyForUse(IsReadyForUseEventArgs e)
{
var handler = IsReadyForUse;
if (handler != null)
{
handler(this, e);
}
}
然后像这样使用它来举起事件:
OnIsReadyForUse(new IsReadyForUseEventArgs("AuthOkay"))
其次,在构造函数中引发事件没有多大意义,因为没有任何东西可能已经订阅了处理程序(除非您将处理程序作为构造函数参数传递)。您需要找到另一个触发器,以便稍后提升事件。
此外,您应该在班级中公开IsReady
属性。因此,如果用户稍后出现,则可以查询该对象是否已准备就绪。如果在某处开始使用该对象时已经引发了IsReady
事件,那么您可能会错过该事件。
编辑:如果您真的想要这样做,可以将处理程序传递给构造函数:
public KSEDataServIO(IsReadyForUseEventHandler handler)
{
IsReadyForUse += handler;
OnIsReadyForUse(new IsReadyForUseEventArgs("AuthOkay")); // see pattern above
}
但是,当您的事件提供this
作为发件人时,您在完成执行整个构造函数之前传递对对象的引用,这可能会导致难以跟踪的问题。如果你要引发事件的唯一地方是构造函数的结束,那么你真的不需要它。
答案 1 :(得分:0)
在分配con_IsReadyForUse
之前,您已在构造函数中引发事件。