在类中引发事件并在另一个类上使用处理程序

时间:2011-12-07 20:15:20

标签: c# events class

我正在创建一个类库,我在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;'在类库中。 有什么想法吗?

2 个答案:

答案 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之前,您已在构造函数中引发事件。