奇怪的NullReferenceException与INotifyPropertyChanged实现

本文关键字:INotifyPropertyChanged 实现 NullReferenceException | 更新日期: 2023-09-27 18:17:40

我在一个基类中实现INotifyPropertyChanged如下:

public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void RaisePropertyChanged(string propertyName)
    {
        var propChangedHandler = PropertyChanged;
        if (propChangedHandler != null)
        {
            var args = new PropertyChangedEventArgs(propertyName);
            propChangedHandler(this, args);
        }
    }
}

我的用法如下:

RaisePropertyChanged("Name");

我得到一个NullReferenceException而参数,"this"和处理程序不为空。有人能解释一下吗?

谢谢。

->异常的完整堆栈跟踪:http://pastebin.com/bH9FeurJ

UPDATE当我覆盖包含此属性的类的实例时,会发生异常。简化的例子:

public class Person : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            RaisePropertyChanged("Name");
        }
    }
// More properties etc.
}

剪断,

public class ViewModel
{
    private Person _dummyPerson;
    public Person DummyPerson
    {
        get { return _dummyPerson; }
        set
        {
            _dummyPerson = value;
            RaisePropertyChanged("DummyPerson");
        }
    }
    public void Foo()
    {
        DummyPerson = new DummyPerson(); 
        // this line throws the NRE, strangly enough the very FIRST time it works fine
    }
}

剪断,

我使用这个DummyPerson和它的Name属性绑定到UI。第二次和之后的所有尝试都导致NullReferenceException

奇怪的NullReferenceException与INotifyPropertyChanged实现

该异常不会在示例代码中引发,而是在订阅的事件处理程序之一中引发。在调试器中一步一步地进行调试,或者在Visual Studio的"调试"-"异常"菜单中为"公共语言运行时异常"打开"抛出"开关。然后你就能找出原因了。

我已经有这个错误一段时间了,然而,我现在已经解决了它(尽管它可能是我的代码中不同的原因)-我(相当愚蠢地)没有检查我的IValueConverter实现之一中的null,(并且由于某种原因,代码不允许我进入此代码)并且在null作为值传递时导致异常。

查看堆栈跟踪,很明显NullReferenceException根本没有被抛出;它实际上被扔到更深的,在:

 GalaSoft.MvvmLight.Command.RelayCommand`1.Execute(Object parameter)

本质上,一个事件侦听器的依赖是错误的。

旁白:我不太确定你正在使用的堆栈跟踪约定是"成长"还是"成长"类型。一旦我看到你的方法上面的方法是委托调用:

System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)