为什么我的事件会抛出空错误?

时间:2012-02-24 18:33:30

标签: c# events nullreferenceexception

由于某种原因,我的事件抛出了一个空错误。我没有看到任何错误。

这是事件

public delegate void connectionSuccess(bool success);
public event connectionSuccess Connection;

然后在一个函数中我有这个女巫抛出空错误

Connection(true);

在另一个调用连接函数的类中编辑*函数

Server.Connection += onConnection;
Server.startConnection();

5 个答案:

答案 0 :(得分:7)

如果未连接,则为null

请改为尝试:

var h = Connection;
if ( h!=null )
{
     h(true);
}

我首先分配一个(本地)变量,以便克服在检查null和调用之间有修改的多线程场景。

即。以下是线程安全的:

if ( Connection!=null )
{
    Connection(true);  // Here, could already be null, again.
}

答案 1 :(得分:0)

在调用之前,您需要检查并确保实际订阅了某些内容。

if(Connection != null)
    Connection(true);

答案 2 :(得分:0)

因为您还没有订阅者。当一个活动没有订阅者时,它变为null。你有两种方法可以解决这个问题(我更喜欢第二种方法)。

选项1:

if (Connection != null)
    Connection(true);

选项2:

public event connectionSuccess Connection = delegate { };

答案 3 :(得分:0)

您收到错误,因为如果存在 null委托引用,则会引发空引用异常!因此,有必要检查代理参考。

最好创建一个事件调用器 - 帮助方法。它简化了对事件处理程序的调用。

例如,让我们看看实现Book接口的INotifyPropertyChanged类:

class Book : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value)
                return;

            _name = value;
            OnPropertyChanged("Name");
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Event invocator.
    /// </summary>
    /// <param name="propertyName">Property name.</param>
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

有关事件调用程序实现的更多详细信息,请访问:Events and Races

答案 4 :(得分:0)

您应该检查对象的初始化。虽然你的代码看起来好像所有东西都在同一个类中,但我不确定为什么你会遇到创建事件的麻烦而不只是调用方法。

但是,如果你在一个课堂上提出这个事件并试图在另一个课堂上处理它,你可能会遇到我做的事情。让我解释一下......

MDIParent - 包含子表单的实例化代码。还有代码将子事件的事件处理程序连接到MDIParent上的代码。

Form x = new MyTestForm();
x.OnMyEvent += this.HandleEvent(myEventArgs);

MDIChild - 包含我们用于创建事件并实际触发它的代码。

public MyTestForm()
{
    public event EventHappened MyEventHandler;
}

稍后在代码中,我们实际上提出了这个事件。

MyEventHandler(new MyEventArgs(this, "some message");

我使用的所有事件处理程序(我们用来更新StatusBar)的问题是,在表单完全初始化之前,事件的连接没有发生。这意味着,当我们实际将事件连接到某个东西时,设置表单的所有工作都已完成!

你怎么解决这个问题?好吧,我将所有初始化代码移动到一个单独的方法中,并且不在构造函数中。我们调用构造函数来创建表单的实例,将事件连接起来,然后运行所有表单的创建任务。

希望这有助于某人!我花了好几天试图找出为什么我的事件是空的,当我能够清楚地看到他们被分配了!