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

本文关键字:处理 程序 内部 事件 另一个 | 更新日期: 2023-09-27 18:17:10

我正在制作一个类库,我在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.
    }
}

然后,在Window Form中我这样做:

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);
}

我得到了一个NullReferenceException行'IsReadyForUse(this, EvArg);'在类库中。你知道吗?

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

您的问题是您在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事件在你开始使用某个对象时已经被触发,那么你可能会错过这个事件。

Edit:如果你真的想这样做,你可以传递一个处理程序给构造函数:

public KSEDataServIO(IsReadyForUseEventHandler handler)
{
   IsReadyForUse += handler;
   OnIsReadyForUse(new IsReadyForUseEventArgs("AuthOkay")); // see pattern above
}

然而,由于您的事件提供this作为发送方,您在完成执行整个构造函数之前传递对对象的引用,可能导致难以追踪的问题。如果你要引发事件的唯一地方是构造函数的末尾,那么你真的不需要它。

在分配con_IsReadyForUse之前,您正在构造函数中引发事件。