Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

When I run this code, it gives:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.

When I do not use INotifyPropertyChanged it works fine. I do not understand cause of problem.

like image 961
Pranit Kothari Avatar asked Nov 27 '22 09:11

Pranit Kothari


2 Answers

There is noone listening to PropertyChanged, which will then be null when trying to call it. Use an OnPropertyChanged method instead:

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

To avoid it being null you have to subscribe to it, for instance from your main method:

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

which is a fancy way of writing

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

Whatever is more clear to you.
You can read more about events here

like image 88
default Avatar answered Dec 18 '22 02:12

default


If nothing has subscribed to the PropertyChanged event, firing the event will throw a NullReferenceException. You need to do a null check before firing the event, like this:

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
}
like image 25
BJ Myers Avatar answered Dec 18 '22 02:12

BJ Myers