---
title: "Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged - Muhammad Rehan Saeed"
description: "An base class implementation for the INotifyPropertyChanged interface. Used in the Model-View-ViewModel (MVVM) pattern. Targeted for best performance."
canonical_url: "https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/"
last_updated: "2014-06-18T00:00:00+00:00"
meta:
  author: "Muhammad Rehan Saeed"
  keywords: ".NET,Base Class Library,BCL,C#,Design Patterns,Events,Explicit Interface Implementation,INotifyPropertyChanged,INotifyPropertyChanging,Model-View-ViewModel (MVVM)"
  "og:description": "An base class implementation for the INotifyPropertyChanged interface. Used in the Model-View-ViewModel (MVVM) pattern. Targeted for best performance."
  "og:image": "https://rehansaeed.com/_og/s/o_4785780b7b9dad10.png"
  "og:image:alt": "Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged - Muhammad Rehan Saeed"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged"
  "twitter:image": "https://rehansaeed.com/_og/s/o_4785780b7b9dad10.png"
  "twitter:image:alt": "Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged - Muhammad Rehan Saeed"
---

> Index of every page on this site: [llms.txt](https://rehansaeed.com/llms.txt)

# [Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged](https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/)

Posted 18 June 2014 - **11 min read**

![MVVM](https://rehansaeed.com/_ipx/f_png&s_2560x1440/images/hero/MVVM-1366x768.png)

1. [Model-View-ViewModel (MVVM) - Overview](https://rehansaeed.com/model-view-viewmodel-mvvm-part1-overview/)
2. [Model-View-ViewModel (MVVM) - IDisposable](https://rehansaeed.com/model-view-viewmodel-mvvm-part2-idisposable/)
3. [Model-View-ViewModel (MVVM) - INotifyPropertyChanged](https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/)
4. [Model-View-ViewModel (MVVM) - INotifyDataErrorInfo](https://rehansaeed.com/model-view-viewmodel-mvvm-part4-inotifydataerrorinfo/)

I know there have been lots of Model-View-ViewModel (MVVM) articles talking about [INotifyPropertyChanged](http://msdn.microsoft.com/en-GB/library/system.componentmodel.inotifypropertychanged.aspx). I've read **lots** of them and this is the aggregation of all the knowledge I've learned plus some cool new stuff (I've not seen it done anywhere else but I could be wrong) which I've also covered in my [Reactive Extensions (Rx) posts](https://rehansaeed.com/reactive-extensions-part1-replacing-events/).

So what are the main aims of a base class implementing [INotifyPropertyChanged](http://msdn.microsoft.com/en-GB/library/system.componentmodel.inotifypropertychanged.aspx)? Well, I think there are a few:

- Performance - Performance is king. It needs to be fast and I mean **really** fast. You can't afford for your UI to freeze up while your view works out all its bindings to the properties in your view model.
- Simplicity - I want to raise property changed events with one line of code and I don't want to mess around with strings if I can help it.
- Reactive Extensions (Rx) - Events are old school, I want an observable property changed event notification system instead of the `PropertyChanged` C# event.
- Human Error - I don't want to raise property change events for properties that don't exist by accident.
- Dependent Properties - Often, the value of one property depends on the value of another. I need to handle this somehow.
- Re-factoring - I don't want my code to break when I rename a property and forget to rename a string too.
- Has it Really Changed - I don't want to raise a property changed event if the value of a property has not really changed.

So, without further ado, here is my implementation.

```cs
namespace Framework.ComponentModel
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Reactive.Linq;
    using System.Reflection;
    using System.Runtime.CompilerServices;

    /// <summary>
    /// Notifies subscribers that a property in this instance is changing or has changed.
    /// </summary>
    public abstract class NotifyPropertyChanges : Disposable, INotifyPropertyChanged //, INotifyPropertyChanging
    {
        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { this.propertyChanged += value; }
            remove { this.propertyChanged -= value; }
        }

        /// <summary>
        /// Occurs when a property value is changing.
        /// </summary>
        // event PropertyChangingEventHandler INotifyPropertyChanging.PropertyChanging
        // {
        //     add { this.PropertyChanging += value; }
        //     remove { this.PropertyChanging -= value; }
        // }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        private event PropertyChangedEventHandler propertyChanged;

        /// <summary>
        /// Occurs when a property value is changing.
        /// </summary>
        // private event PropertyChangingEventHandler PropertyChanging;

        /// <summary>
        /// Gets the when property changed observable event. Occurs when a property value changes.
        /// </summary>
        /// <value>
        /// The when property changed observable event.
        /// </value>
        public IObservable<string> WhenPropertyChanged
        {
            get
            {
                this.ThrowIfDisposed();

                return Observable
                    .FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                        h => this.propertyChanged += h,
                        h => this.propertyChanged -= h)
                    .Select(x => x.EventArgs.PropertyName);
            }
        }

        /// <summary>
        /// Gets the when property changing observable event. Occurs when a property value is changing.
        /// </summary>
        /// <value>
        /// The when property changing observable event.
        /// </value>
        // public IObservable<EventPattern<PropertyChangingEventArgs>> WhenPropertyChanging
        // {
        //     get
        //     {
        //         return Observable
        //             .FromEventPattern<PropertyChangingEventHandler, PropertyChangingEventArgs>(
        //                 h => this.PropertyChanging += h,
        //                 h => this.PropertyChanging -= h)
        //             .AsObservable();
        //     }
        // }

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            Debug.Assert(
                string.IsNullOrEmpty(propertyName) ||
                (this.GetType().GetRuntimeProperty(propertyName) != null),
                "Check that the property name exists for this instance.");

            PropertyChangedEventHandler eventHandler = this.propertyChanged;

            if (eventHandler != null)
            {
                eventHandler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>
        /// <param name="propertyNames">The property names.</param>
        protected void OnPropertyChanged(params string[] propertyNames)
        {
            if (propertyNames == null)
            {
                throw new ArgumentNullException(nameof(propertyNames));
            }

            foreach (string propertyName in propertyNames)
            {
                this.OnPropertyChanged(propertyName);
            }
        }

        /// <summary>
        /// Raises the PropertyChanging event.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
        {
            Debug.Assert(
                string.IsNullOrEmpty(propertyName) ||
                (this.GetType().GetRuntimeProperty(propertyName) != null),
                "Check that the property name exists for this instance.");

            // PropertyChangingEventHandler eventHandler = this.PropertyChanging;

            // if (eventHandler != null)
            // {
            //     eventHandler(this, new PropertyChangingEventArgs(propertyName));
            // }
        }

        /// <summary>
        /// Raises the PropertyChanging event.
        /// </summary>
        /// <param name="propertyNames">The property names.</param>
        protected void OnPropertyChanging(params string[] propertyNames)
        {
            if (propertyNames == null)
            {
                throw new ArgumentNullException(nameof(propertyNames));
            }

            foreach (string propertyName in propertyNames)
            {
                this.OnPropertyChanging(propertyName);
            }
        }

        /// <summary>
        /// Sets the value of the property to the specified value if it has changed.
        /// </summary>
        /// <typeparam name="TProp">The type of the property.</typeparam>
        /// <param name="currentValue">The current value of the property.</param>
        /// <param name="newValue">The new value of the property.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns><c>true</c> if the property was changed, otherwise <c>false</c>.</returns>
        protected bool SetProperty<TProp>(
            ref TProp currentValue,
            TProp newValue,
            [CallerMemberName] string propertyName = null)
        {
            this.ThrowIfDisposed();

            if (!object.Equals(currentValue, newValue))
            {
                this.OnPropertyChanging(propertyName);
                currentValue = newValue;
                this.OnPropertyChanged(propertyName);

                return true;
            }

            return false;
        }

        /// <summary>
        /// Sets the value of the property to the specified value if it has changed.
        /// </summary>
        /// <typeparam name="TProp">The type of the property.</typeparam>
        /// <param name="currentValue">The current value of the property.</param>
        /// <param name="newValue">The new value of the property.</param>
        /// <param name="propertyNames">The names of all properties changed.</param>
        /// <returns><c>true</c> if the property was changed, otherwise <c>false</c>.</returns>
        protected bool SetProperty<TProp>(
            ref TProp currentValue,
            TProp newValue,
            params string[] propertyNames)
        {
            this.ThrowIfDisposed();

            if (!object.Equals(currentValue, newValue))
            {
                this.OnPropertyChanging(propertyNames);
                currentValue = newValue;
                this.OnPropertyChanged(propertyNames);

                return true;
            }

            return false;
        }

        /// <summary>
        /// Sets the value of the property to the specified value if it has changed.
        /// </summary>
        /// <param name="equal">A function which returns <c>true</c> if the property value has changed, otherwise <c>false</c>.</param>
        /// <param name="action">The action where the property is set.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns><c>true</c> if the property was changed, otherwise <c>false</c>.</returns>
        protected bool SetProperty(
            Func<bool> equal, 
            Action action,
            [CallerMemberName] string propertyName = null)
        {
            this.ThrowIfDisposed();

            if (equal())
            {
                return false;
            }

            this.OnPropertyChanging(propertyName);
            action();
            this.OnPropertyChanged(propertyName);

            return true;
        }

        /// <summary>
        /// Sets the value of the property to the specified value if it has changed.
        /// </summary>
        /// <param name="equal">A function which returns <c>true</c> if the property value has changed, otherwise <c>false</c>.</param>
        /// <param name="action">The action where the property is set.</param>
        /// <param name="propertyNames">The property names.</param>
        /// <returns><c>true</c> if the property was changed, otherwise <c>false</c>.</returns>
        protected bool SetProperty(
            Func<bool> equal, 
            Action action,
            params string[] propertyNames)
        {
            this.ThrowIfDisposed();

            if (equal())
            {
                return false;
            }

            this.OnPropertyChanging(propertyNames);
            action();
            this.OnPropertyChanged(propertyNames);

            return true;
        }
    }
}
```

# Simple Example

An example of how you can use this base class is as follows.

```cs
public class CatCountViewModel : NotifyPropertyChanges
{
    private int numberOfCats;

    public int NumberOfCats
    {
        get => this.numberOfCats;
        set => this.SetProperty(ref this.numberOfCats, value);
    }
}
```

# Performance

As I said before, performance is king. A slow application is a frustrating application. However, there has always been a problem. When you want to raise a property changed event, you have to pass in a string. We can't check the validity of the string at compile time, only at runtime. So we can get errors due to typos etc. which can get overlooked.

There are a lot of implementations of [INotifyPropertyChanged](http://msdn.microsoft.com/en-GB/library/system.componentmodel.inotifypropertychanged.aspx) that use reflection or expression trees and as [this](http://blog.quantumbitdesigns.com/2010/01/26/mvvm-lambda-vs-inotifypropertychanged-vs-dependencyobject) and [this](http://blog.amusedia.com/2013/06/inotifypropertychanged-implementation.html) blog show, using reflection is a terribly slow method of raising an event and to be avoided.

Luckily, Microsoft introduced the [CallerMemberNameAttribute](http://msdn.microsoft.com/en-gb/library/system.runtime.compilerservices.callermembernameattribute.aspx) attribute, which means that as in the above example, we don't need to add a string for the property name, it gets added for us to the last optional parameter in the `SetProperty` method.

The `SetProperty` method uses the [ref keyword](http://msdn.microsoft.com/en-us/library/14akc2c7.aspx) to pass the parameter by reference (Passing parameters by reference is faster). It then checks to see if the `numberOfCats` parameter is different from the `value` parameter (There is no point raising a property changed event if they are the same). Only then, do we raise a property changed event.

# Handling Dependent Properties

But what about dependent properties. Where one property affects the value of another. Well, lets take a look at another example.

```cs
public class CatCounter : NotifyPropertyChanges
{
    private int numberOfCats;

    public int NumberOfCats
    {
        get => this.numberOfCats;
        set => this.SetProperty(ref this.numberOfCats, value, "NumberOfCats", "NumberOfCatsDescription");
    }

    public string NumberOfCatsDescription => $"{this.NumberOfCats} Cats Counted";
}
```

You can see, that I've not done anything spectacular and just passed in the strings. As I'm using the [params](http://msdn.microsoft.com/en-us/library/w5zay9db.aspx) keyword, you can pass in as many strings as you want and the `SetProperty` method will raise a property changed event for each one.

If you give me a moment, I will explain why I think this is the right compromise to make. Lets make no mistake, you do need to compromise between performance and simplicity/maintainability. There are approaches which make this eventuality simpler and easier to understand but they can and will degrade performance.

So does using strings cause problems? First of all, if you use a Visual Studio Add-in like Resharper, this problem is [solved](http://blog.jetbrains.com/dotnet/2012/07/24/inotifypropertychanged-support-in-resharper-7) as it checks that the strings match the property name for you. Secondly, as a backup the `OnPropertyChanged` method in the implementation above contains some `Debug.Assert` statements (These are removed in Release mode and have no effect on performance) to check that the property names exist and are correct, if they are not you get a error message. Thirdly, this is fairly rare in my experience and I can deal with the overhead of having a couple of extra strings.

Again, this is a choice I've made to go with performance over maintainability.

# Dealing with Wrapped Objects

What if you want to wrap an object that looks like the one below with a class that supports [INotifyPropertyChanged](http://msdn.microsoft.com/en-GB/library/system.componentmodel.inotifypropertychanged.aspx)? This is a scenario I have not seen many people cover but occurs fairly often in my experience.

```cs
public class CatCount
{
    public int Count { get; set; }
}
```

An example view model for the CatCount class can be found below.

```cs
public class CatCountModel : NotifyPropertyChanges
{
    private CatCount catCount;

    public int NumberOfCats
    {
        get { return this.catCount.Count; }
        set { this.SetProperty(() => this.catCount.Count == value, () => this.catCount.Count = value); }
    }
}
```

So here we are providing the `SetProperty` method with two delegates. We can't use the ref keyword we used earlier because this gives us the compiler error "A property, indexer or dynamic member access may not be passed as an out or ref parameter". So we use delegates as an alternative which is not as fast as the ref keyword but almost as fast.

The first delegate determines if the cat count has actually changed. Only if it has (Remember, executing a delegate is far cheaper than updating the UI), do we call the next delegate which actually sets the value. Finally the `SetProperty` method raises a property changed event.

# Using Reactive Extensions (Rx) to Replace the PropertyChanged Event

C# events are old school. Reactive Extensions (Rx) provides a cleaner and far more powerful drop-in replacement for C# events. I'm not going to go over the advantages of Reactive Extensions here but you can take a look at a series of blog posts I've done in the [past](https://rehansaeed.com/reactive-extensions-part1-replacing-events/).

We can hide the `PropertyChanged` C# event by explicitly implementing the interface (Click [here](http://stackoverflow.com/questions/143405/c-sharp-interfaces-implicit-implementation-versus-explicit-implementation) for details on implicit versus explicit implementations of interfaces).

The `PropertyChanged` C# event can still be accessed by first casting the object to [INotifyPropertyChanged](http://msdn.microsoft.com/en-GB/library/system.componentmodel.inotifypropertychanged.aspx). Binding in XAML languages, which uses this interface continues to work. Our new Reactive Extensions (Rx) observable event called `WhenPropertyChanged` of type `IObservable<string>` (The string is the property name) is now the default method of subscribing for property changed events and we've hidden away the old C# event.

# Implementing INotifyPropertyChanging

Take another look at the title of this paragraph, it says [INotifyPropertyChang**ing**](http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanging%28v=vs.110%29.aspx) and not [INotifyPropertyChang**ed**](http://msdn.microsoft.com/en-GB/library/system.componentmodel.inotifypropertychanged.aspx).

This interface has a single event called `PropertyChang**ing**` and is raised **before** a property is about to be changed. This interface is not actually used by any XAML framework but does complement the `INotifyPropertyChanged` interface and can be useful in your view models when you want to know that a property is about to change and do something about it.

Given that we've written a base class, it is super easy to include it too. You should note that this interface only exists in the full .NET Framework and Silverlight. It does not exist on Windows Store or Windows Phone platforms.

As we are writing a base class for a Portable Class Library (PCL), I've commented it out. However, if I were to create a full .NET or Silverlight class library, I would definitely put that code back in.

If you find the interface useful and you too are using a Portable Class Library (PCL), you could take a copy of the `INotifyPropertyChanging` interface and include it with your base class. If Microsoft ever decide to include it into the PCL, you simply need to remove your class and use the one in the framework.

# Conclusions

I have gone through many iterations to get to this base class. As I've shown, I've had very particular goals in mind. Your mileage may vary but I believe with the tools Microsoft have given us, this is a good compromise and covers all the scenarios I can think of. I'd be very interested if anyone has any comments or thoughts on improvements. Feel free to sound-off in the comments.

## Web Mentions

[What's this?](https://en.wikipedia.org/wiki/Webmention)

### 0 Linked

### 0 Replies

## GitHub Comments

### 16 Comments

[Comment on GitHub](https://github.com/RehanSaeed/rehansaeed.github.io/issues/92)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Mahgnilloc](https://camo.githubusercontent.com/2ed3c0a5ab1c196d6b4f447e4e09b74aa77a0979e934889a46794d0cec075e70/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65643536393037323266643363613639303961303765306263626361643436343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/2ed3c0a5ab1c196d6b4f447e4e09b74aa77a0979e934889a46794d0cec075e70/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65643536393037323266643363613639303961303765306263626361643436343f733d393626643d6d6d26723d67) **Mahgnilloc** commented on **2014-09-03 07:34:00**

Thanks, your wrapped property really helped me.

I think you missed out the equals check in the two `SetProperty` functions though

```
if (equal()) return false;
```

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **Muhammad Rehan Saeed** commented on **2014-09-04 08:03:54**

> Thanks, your wrapped property really helped me.
>
> I think you missed out the equals check in the two `SetProperty` functions though
>
> ```
> if (equal()) return false;
> ```

Thanks for the comment Mahgnilloc. I've updated the code to reflect your comment.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Rached](https://camo.githubusercontent.com/3eb5c4fbb36a579c3d13b32d02dbfd170e60a0e08659118b8e703c99034e44d7/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f64323633343130386661333938663364373833663664633661383230663763393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/3eb5c4fbb36a579c3d13b32d02dbfd170e60a0e08659118b8e703c99034e44d7/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f64323633343130386661333938663364373833663664633661383230663763393f733d393626643d6d6d26723d67) **Rached** commented on **2015-08-17 16:44:57**

> Thanks for the comment Mahgnilloc. I've updated the code to reflect your comment.

Your blog series on mvvm is helping me a lot, thanks.. the `SetProperty` should be bool instead of void.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2015-08-18 12:07:54**

> Your blog series on mvvm is helping me a lot, thanks.. the `SetProperty` should be bool instead of void.

Well spotted, thanks. Fixed.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Manthravadi, Siva Harsha Vardhan](https://camo.githubusercontent.com/49e3d731edc2653e27327c0bcd7429d9c980d90d1c30dc4ba3e7245197439b51/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f30653534613032383834383435383935373566333138396334333936313932643f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/49e3d731edc2653e27327c0bcd7429d9c980d90d1c30dc4ba3e7245197439b51/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f30653534613032383834383435383935373566333138396334333936313932643f733d393626643d6d6d26723d67) **Manthravadi, Siva Harsha Vardhan** commented on **2015-10-17 17:48:17**

`Disposable` cannot be inherited anymore ...do you see any other alternatives?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2015-10-21 17:11:49**

> `Disposable` cannot be inherited anymore ...do you see any other alternatives?

Not sure what you mean. Have you set the class to sealed?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Dieter](https://camo.githubusercontent.com/618ebd2b0a25894b1ac19c3de4418e06ec26803ea367b81899f25d905303466c/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f39343835376432353535356232646232623465613735333838633663646161623f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/618ebd2b0a25894b1ac19c3de4418e06ec26803ea367b81899f25d905303466c/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f39343835376432353535356232646232623465613735333838633663646161623f733d393626643d6d6d26723d67) **Dieter** commented on **2016-01-16 13:50:00**

Hello Rehan,

Great implementation.

Just a minor finding:  
 I guess there's a typo in your 'Dealing with Wrapped Objects' example. The `==` and `=` should be flipped.

Have a great weekend  
 Dieter

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2016-01-26 08:43:59**

> Hello Rehan,
>
> Great implementation.
>
> Just a minor finding:  
>  I guess there's a typo in your 'Dealing with Wrapped Objects' example. The `==` and `=` should be flipped.
>
> Have a great weekend  
>  Dieter

Actually no, the second delegate is passed to determine whether the two objects are equal. Only if they are equal, do we raise a property changed event.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Dieter](https://camo.githubusercontent.com/be23dd5e371566fef65db25ae02aec6ceb04083abe26bdc70399cf2f2807a46a/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32616465626166376639326431313731373135363361333637353236303561393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/be23dd5e371566fef65db25ae02aec6ceb04083abe26bdc70399cf2f2807a46a/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32616465626166376639326431313731373135363361333637353236303561393f733d393626643d6d6d26723d67) **Dieter** commented on **2016-05-26 08:56:55**

> Actually no, the second delegate is passed to determine whether the two objects are equal. Only if they are equal, do we raise a property changed event.

Hello Rehan,

Are you sure?  
 The procedure is

```
protected Boolean SetProperty(Func equal, Action action, [CallerMemberName] String propertyName = null)
```

So the first delegate seems to be the equality check.

Testing your example only works if I'm using

```
set { this.SetProperty(() => this.catCount.Count == value, () => this.catCount.Count = value); }
```

Instead of

```
set { this.SetProperty(() => this.catCount.Count = value, () => this.catCount.Count == value); }
```

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2016-05-26 17:16:08**

> Hello Rehan,
>
> are you sure?  
>  The procedure is
>
> ```
> protected Boolean SetProperty(Func equal, Action action, [CallerMemberName] String propertyName = null)
> ```
>
> So the first delegate seems to be the equality check.
>
> Testing your example only works if I'm using
>
> ```
> set { this.SetProperty(() => this.catCount.Count == value, () => this.catCount.Count = value); }
> ```
>
> Instead of
>
> ```
> set { this.SetProperty(() => this.catCount.Count = value, () => this.catCount.Count == value); }
> ```

Scratch that, you are absolutely correct sir! It's been some time since I've looked at this code.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Ole Kristian](https://camo.githubusercontent.com/c2fa2b5e9d3cd2cb9f688507bf4f90d232a7e1d83a7c9101667a3b25dc8a368e/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32303930616532616537653865303333623235663530313932396639396439393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/c2fa2b5e9d3cd2cb9f688507bf4f90d232a7e1d83a7c9101667a3b25dc8a368e/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32303930616532616537653865303333623235663530313932396639396439393f733d393626643d6d6d26723d67) **Ole Kristian** commented on **2017-10-23 22:43:15**

> Scratch that, you are absolutely correct sir! It's been some time since I've looked at this code.

Maybe update the example to reflect this change?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2017-11-13 09:16:30**

> Maybe update the example to reflect this change?

Thanks, have done so!

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Bilal](https://camo.githubusercontent.com/683fee3347043ac7357d1d9fc3d2babfb4227d3e6f6277eda558daf54908684b/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f39373666623336386534613261303035303661343539313964336264633865383f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/683fee3347043ac7357d1d9fc3d2babfb4227d3e6f6277eda558daf54908684b/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f39373666623336386534613261303035303661343539313964336264633865383f733d393626643d6d6d26723d67) **Bilal** commented on **2019-04-24 12:44:31**

I want to ask you if I could have the permission to use your code freely.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2019-05-03 13:44:09**

> I want to ask you if I could have the permission to use your code freely.

The code in this post is MIT licensed.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Steve Greene](https://camo.githubusercontent.com/9f35d5aab51e9d4f95532c1bbf4a148d6829634dcfae051ee328df05f9771126/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f38316332656234666261353336373561323162623034363863376534333434393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/9f35d5aab51e9d4f95532c1bbf4a148d6829634dcfae051ee328df05f9771126/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f38316332656234666261353336373561323162623034363863376534333434393f733d393626643d6d6d26723d67) **Steve Greene** commented on **2019-07-31 19:39:02**

This `INotifyPropertyChanged` base implementation seems very useful to me - thank you!

I'm confused about the `Debug.Assert` condition shown:

```
string.IsNullOrEmpty(propertyName) || (this.GetType().GetRuntimeProperty(propertyName) != null)
```

Shouldn't that be like this instead?

```
(!string.IsNullOrEmpty(propertyName)) && (this.GetType().GetRuntimeProperty(propertyName) != null)
```

But I'm unfamiliar with the actual meaning of `this.GetType().GetRuntimeProperty(propertyName)`, so I'm just confused.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed "RehanSaeed")

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2019-08-02 16:28:51**

> This `INotifyPropertyChanged` base implementation seems very useful to me - thank you!
>
> I'm confused about the `Debug.Assert` condition shown:
>
> ```
> string.IsNullOrEmpty(propertyName) || (this.GetType().GetRuntimeProperty(propertyName) != null)
> ```
>
> Shouldn't that be like this instead?
>
> ```
> (!string.IsNullOrEmpty(propertyName)) && (this.GetType().GetRuntimeProperty(propertyName) != null)
> ```
>
> But I'm unfamiliar with the actual meaning of `this.GetType().GetRuntimeProperty(propertyName)`, so I'm just confused.

A null or empty property name is actually valid. It signals that all of the properties on the view model have changed and that they should be refreshed in the XAML bindings.

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://rehansaeed.com/#website","@type":"WebSite","description":"Software Developer at Microsoft, YouTuber, Open Source Contributor and Blogger","inLanguage":"en-GB","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/","author":{"@id":"https://rehansaeed.com/#identity"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://rehansaeed.com/?search={search_term_string}"},"query-input":"required name=search_term_string"}],"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/#webpage","@type":"WebPage","dateModified":"2014-06-18T00:00:00+00:00","datePublished":"2014-06-18T00:00:00+00:00","description":"An base class implementation for the INotifyPropertyChanged interface. Used in the Model-View-ViewModel (MVVM) pattern. Targeted for best performance.","name":"Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged","url":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/","breadcrumb":{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/#breadcrumb"},"isPartOf":{"@id":"https://rehansaeed.com/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/"]}]},{"@id":"https://rehansaeed.com/#identity","@type":"Person","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/about/","image":{"@id":"https://rehansaeed.com/#/schema/image/1"},"sameAs":["https://github.com/RehanSaeed","https://www.linkedin.com/in/muhammad-rehan-saeed","https://stackoverflow.com/users/1212017/muhammad-rehan-saeed","https://www.youtube.com/c/MuhammadRehanSaeed","https://www.twitch.tv/rehansaeeduk"]},{"@id":"https://rehansaeed.com/#publisher","@type":"Organization","logo":"https://rehansaeed.com/images/schema/Publisher-600x60.png","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com"},{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/#article","@type":"Article","dateModified":"2014-06-18T00:00:00+00:00","datePublished":"2014-06-18T00:00:00+00:00","description":"An base class implementation for the INotifyPropertyChanged interface. Used in the Model-View-ViewModel (MVVM) pattern. Targeted for best performance.","headline":"Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged","inLanguage":"en-GB","url":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/","author":{"@id":"https://rehansaeed.com/#identity"},"image":[{"@type":"ImageObject","url":"https://rehansaeed.com/images/hero/MVVM-1366x768.png","caption":"MVVM","width":"1366","height":"768"}],"isPartOf":{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/#webpage"},"keywords":[".NET","Base Class Library","BCL","C#","Design Patterns","Events","Explicit Interface Implementation","INotifyPropertyChanged","INotifyPropertyChanging","Model-View-ViewModel (MVVM)"],"mainEntityOfPage":{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/#webpage"},"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://rehansaeed.com/","position":1},{"@type":"ListItem","name":"Model-View-ViewModel (MVVM) - Part 3 - INotifyPropertyChanged","item":"https://rehansaeed.com/model-view-viewmodel-mvvm-part3-inotifypropertychanged/","position":2}]},{"@id":"https://rehansaeed.com/#/schema/image/1","@type":"ImageObject","contentUrl":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png","inLanguage":"en-GB","url":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png"}]}
```

## Sitemap

See the full [sitemap](https://rehansaeed.com/sitemap.md) for all pages.
