3

当我尝试从 Form B 发送一个字符串以形成 a 时,我的代码中有一个非常烦人的问题。我收到错误消息:

Object reference not set to an instance of an object.

我对这个错误很熟悉,通常我知道如何解决这个问题,但是这个不同。

我需要将时钟名称从一个表单发送到主表单,我正在尝试使用下面的代码来实现这一点:

delegate void ClockClocknameReceivedEventHandler(object sender, Clock.ClocknameReceivedEventArgs e);

    internal class ClocknameReceivedEventArgs : EventArgs
    {
        string _clockname;

        public string Clockname
        {
            get { return _clockname; }
        }

        public ClocknameReceivedEventArgs(string clockname)
        {
            _clockname = clockname;
        }
    }

    // An event that clients can use to be notified whenever the
    // elements of the list change.
    public event ClockClocknameReceivedEventHandler ClocknameReceived;

    // Invoke the Changed event; called whenever list changes
    protected void OnClocknameReceived(Clock.ClocknameReceivedEventArgs e)
    {
        ClocknameReceived(this, e);
    }

按下按钮时会触发以下代码,然后表单将关闭:

OnClocknameReceived(new Clock.ClocknameReceivedEventArgs(ClockName));

我收到的错误(对象引用未设置为对象的实例。)发生在

ClocknameReceived(this, e);

我正在使用完全相同的代码,从另一个类到主表单来发送一个工作正常的字节数组,但是这个给了我这个错误。

有人有什么想法吗?

提前致谢!

4

3 回答 3

4

代表可以是null. 仅在不是时才调用它null

protected void OnClocknameReceived(Clock.ClocknameReceivedEventArgs e)
{
    ClockClocknameReceivedEventHandler handler = ClocknameReceived;
    if (handler != null)
    {
        handler(this, e);
    }
}

委托是null当您尚未为事件订阅事件处理程序时。订阅事件处理程序:

formB.ClocknameReceived += FormB_ClocknameReceived;

void FormB_ClocknameReceived(object sender, Clock.ClocknameReceivedEventArgs e)
{
    MessageBox.Show(e.Clockname);
}
于 2013-02-15T14:08:04.997 回答
1

您不检查是否ClocknameReceived已分配事件(即有任何订阅者)。典型的事件处理代码通常如下所示:

var handler = ClocknameReceived;
if (handler != null)
{
    handler(this, e);
}

这种类型的方法还可以(在一定程度上)缓解事件处理程序的竞争条件,因为它可能在您触发它时未被分配。

查看您的代码,您绝对可以整理一下。一方面,你的EventArgs类可以用更少的代码重写:

internal class ClocknameEventArgs : EventArgs
{
    public ClockNameEventArgs(string name)
    {
        Name = name;
    }

    public string Name { get; private set; }
}

然后在您的表单中,如果您有特定类型的 ,则不需要委托EventArgs,您的事件可以声明为:

public event EventHandler<Clock.ClocknameEventArgs> ClocknameReceived;

然后你在某个地方连接到这个事件(也许在FormCreate事件中?):

ClocknameReceived += (sender, args) {
    FormB.PassName(args.Name);
};
于 2013-02-15T14:09:28.880 回答
0

您必须检查事件是否有委托

if( ClocknameReceived != null)
    ClocknameReceived(this, e);
于 2013-02-15T14:11:07.480 回答