簡體   English   中英

將值設置為屬性時的NullReferenceException

[英]NullReferenceException when set value to a property

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

當我運行此代碼時,它給出:

未處理的異常:System.NullReferenceException:未將對象引用設置為對象的實例。

當我不使用INotifyPropertyChanged它工作正常。 我不明白問題的原因。

沒有人會收聽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");
    }
}

要避免它為null您必須訂閱它,例如從您的main方法:

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

這是一種奇特的寫作方式

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

無論你怎么說都清楚。
您可以在此處閱讀有關活動的更多信

如果沒有訂閱PropertyChanged事件,則觸發該事件將拋出NullReferenceException 在觸發事件之前需要進行空檢查,如下所示:

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
}

PropertyChanged委托沒有監聽器。 在引發委托之前,應始終檢查委托是否為空。

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
}

此外,從您的代碼判斷,您可能意味着在更改屬性時調用OnPropertyChanged 為此,您應該向PropertyChanged添加事件偵聽器,並在偵聽器中調用OnPropertyChanged 您可以通過添加以下代碼來完成:

//Old ctor
public Cls()
{
    PropertyChanged += new PropertyChangedEventHandler(Cls_PropertyChanged); //Register the event handler
    MyProperty = "Hello";
}

void Cls_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    OnPropertyChanged(e.PropertyName); //Call your method
}

我收到了'viewmodel'類中的錯誤,因為我省略了INotifyPropertyChanged接口聲明。

所以從這樣的事情

public class viewmodel
   {}

對此

public class viewmodel: INotifyPropertyChanged
 {}

修復。


對OP來說沒有幫助,但是其他人可能會做出疏忽?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM