将值设置为属性时的NullReferenceException

Pra*_*ari 4 .net c# exception inotifypropertychanged

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Cls : INotifyPropertyChanged
    {
        private string my;
        public  string MyProperty
        {
            get
            {
                return my;
            }
            set
            {
                my = value;
                PropertyChanged(this, new PropertyChangedEventArgs("MyProperty")); 
            }

        }

        public Cls()
        {
            MyProperty = "Hello";
        }

        public void print()
        {
            Console.WriteLine(MyProperty);
        }

        protected virtual void OnPropertyChanged(string name)
        {
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }

    class Program
    {
        static void Main(string[] args)
        {
            Cls s = new Cls();
            s.print();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,它给出:

未处理的异常:System.NullReferenceException:未将对象引用设置为对象的实例.

当我不使用INotifyPropertyChanged它工作正常.我不明白问题的原因.

Def*_*ult 20

没有人听PropertyChanged,在尝试调用它时将为null.OnPropertyChanged改为使用方法:

private void OnPropertyChanged(string propertyName){
    var handler = PropertyChanged;
    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propertyName));

    // With C# 6 this can be replaced with
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public  string MyProperty
{
    get { return my; }
    set
    {
       if (my == value)
           return;

        my = value;
        OnPropertyChanged("MyProperty");
    }
}
Run Code Online (Sandbox Code Playgroud)

为了避免它,null你必须订阅它,例如从你的main方法:

static void Main(string[] args){
    Cls s = new Cls();
    s.PropertyChanged += (sender, args) => MessageBox.Show("MyProperty changed!");
    s.print();
}
Run Code Online (Sandbox Code Playgroud)

这是一种奇特的写作方式

static void Main(string[] args){
    Cls s = new Cls();
    s.PropertyChanged += ShowMessage;
    s.print();
}

private void ShowMessage(object sender, PropertyChangedEventArgs args){
    MessageBox.Show("MyProperty changed!");
}
Run Code Online (Sandbox Code Playgroud)

无论你怎么说都清楚.
您可以在此处阅读有关活动的更多信


BJ *_*ers 5

如果没有订阅该PropertyChanged事件,则触发该事件将抛出一个NullReferenceException.在触发事件之前需要进行空检查,如下所示:

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
}
Run Code Online (Sandbox Code Playgroud)