Basic MVVM Base class / INotifyPropertyChanged implementation

A while back, (OK, a long while back), I promised an article on how to create a MMVM view model base class.  This class will implement the INotifyPropertyChanged interface, and add some common sugar on top of it to make it really easy to use.

In all project types that use XAML, you can bind items in the UI to properties in the view model. The purpose of INotifyPropertyChanged is to notify those binding of when the underlying property changes so the updated values can be pulled in. It has one item, an event called PropertyChanged. However, just adding an event is not super helpful. So here’s an example of a base class that adds a bit more.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace MVVMBase
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        //The interface only includes this evennt
        public event PropertyChangedEventHandler PropertyChanged;

        //Common implementations of SetProperty
        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
        {
            bool propertyChanged = false;

            //If we have a different value, do stuff
            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                field = value;
                OnPropertyChanged(name);
                propertyChanged = true;
            }

            return propertyChanged;
        }

        //The C#6 version of the common implementation
        protected void OnPropertyChanged([CallerMemberName]string name = null)
        {
           PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

So what does it do:

  1. Implement INotifyPropertyChanged – yup, the event is there, job done.
  2. Creates a handy SetProperty method that does the following:
    1. Takes the property name, a reference to it’s backing field and the new value
    2. Checks if the new value is actually different
    3. If so it updates the backing field and invokes the property changed event
    4. Returns a value to indicate if the property actually changed
  3. Creates an OnPropertyChanged method (this is often also called RaisePropertyChanged) that can be used to force the PropertyChanged event to fire for a given property.

Now that I’ve got this, using it is pretty simple. First, make you view models inherit from this. Then write your properties this way:

private bool _messageReady;
public bool MessageReady
{
    get { return _messageReady; }
    set { SetProperty(ref _messageReady, value); }
}

Note that although SetProperty is generic, you don’t have to pass in a Type, and although it takes 3 propereties, and the third is the name of the property is being changed, you don’t have to as the default is set to the CallerMemberName attribute. Of course, you can do both and if you needed to do some thing where you set the property indirectly as part of some other method, you could then call SetProperty<bool>(ref _messageReady, true, “MessageReady”);

Some Properties are getter only and depend on the values of other properties and fields in the class. This is a place where that OnPropertyChanged method is useful.

private bool _messageReady; 
public bool MessageReady 
{ 
    get { return _messageReady; } 
    set 
    { 
        if (SetProperty(ref _messageReady, value))
        {
            OnPropertyChanged(() => BackgroundColor);
        }
    } 
}

public Color BackgroundColor
{
    get { return MessageReady ? Colors.Green : Colors.White.
}

In this example, we have a property called BackgroundColor that is normally white, but becomes green when a message is ready. But as it’s just a getter, how does our UI know when it’s value changes? We call OnPropertyChanged for BackgroundColor when the MessageReady property is updated.

So that’s a brief tour of a view model base class.  If you look around, you will find others who may have more, or that have different implementations of these methods. For me, this is the basics of what you need – an implementation of INotifyPropertyChanged that you only need to make once, and that makes updating bound properties easy to do.

CodeSample: MVVMBase.zip

Covariance and Contravariance

OK, so this is my attempt to help me to commit something to memory. I am not an expert in this area by any means.

Variance which is, loosely, the subtyping relationship for objects and substitutions that may be permitted for those types. Generally, more derived types can be assigned to objects of less derived types e.g Cat objects can be used in places where we call for an Animal. This particular type of variance is called co-variance, but there is also Contravariance and Invariance in C# types.

Generally speaking….

Covariance allows you to return a more derived class from a method. True contravariance would allow you to change the method signature so you would have in the Animal class, a method Animal GetAnimal() and in the Cat class, it’s override as Cat GetAnimal().

Contravariance would allow a less derived class to be used in method arguments so if the Animal class had a method called BuyAnimal(Animal animal), the Cat class could override this with BuyAnimal(Object animal).

Neither of these are supported in C#, though Java & C++ have some support.  So what do we need to know about convariance and contravariance in C# or .Net?

Covariance

Some sources refer to it as preserving the standard variance or similar words to that. Basically, it means that if I override a method, the return can be the same as the parent, or a descendant type. This sounds a lot like following the standard inheritance pattern, and while methods in a subclass can’t declare a more derived return type when overriding base class methods, they can of course return a more derived type. Maybe calling this covariance is generous, though it meets some of the definition, as it’s really just polymorphism that is a part of object oriented languages.

More explicit examples of Covariance can be found in generic types, such as IEnumerable<T> and in usage, it looks pretty much the same. The key here is that a generic method can return either T or a subclass of T and can be declared to return different T’s. This works because IEnumerable uses the ‘out’ variance modifier.

//Covariance - all bout how the return type can be a child of a parent
Animal spot = new Dog(Gender.Male);
Animal[] mammals = new Mammal[10];
IEnumerable<Animal> animals = new List<Dog>();

You can also see covariance in IEnumerator<T>, IQueryable<T> and IGrouping<TKey, TElement>.

Contravariance

Contravariance is reversing this – contrary to the normal variance. In C# Contravariance is limited to delegates and interfaces It means that I am allowed to change the input args to a base class of whatever the args the base class takes. In the case of delegates, I can assign a more general method to more specific delegate.

static void Main(string[] args)
{
  //Contravariance lets a method take parameters that are from a superclass of the type expected by a
  //delegate.
        //Here the delegate takes a Dog
  Dog dog = new Dog(Gender.Female);
  Action<Dog> barkingDog = Bark;
  barkingDog(dog);
}		

//Method here takes a Animal
public static void Bark(Animal animal)
{
  Console.WriteLine($"Woof, im a {nameof(animal)}");
}

You may look at the code above and say, what’s the point of that? While it’s true that it doesn’t buy us much in this case, consider scenarios where those delegates are representing methods with a less direct relationship. In this case it starts to become more useful. For example, if the Dog class has a property called Action<Dog TalkDelegate. You can pass the Bark(Animal animal) method to that property, even though the method signature doesn’t match what the property requires. This is because as Dog is a Subclass of animal, a method working with an animal will also be able to work with a Dog.

You also see Contravaraince in IComparer<T>, IEqualityComparer<T> and ICompatible<T>

Invariant classes

Some types and interfaces are invariant. For example, while IEnumberable<T> is covariant. ILIst<T> is invariant. That means that the code below will not compile.

//Invariance
IList<Animal> animals = new List<Dog>();

Variance Modifiers

There are two variance modifiers that can be applied: ‘in’ and ‘out’. Only delegates and Interfaces can take Variance modifiers. The reason IEnumerable supports Covariance is that it’s declared as IEnumerable<out T>, and delegates by default are constructed using ‘in’, such as Action<in T>. These keywords can be seen a linking the variance of the output or the inputs.

  • out T – Covariance lets a method return a value from a subclass of the result expected by a delegate
  • in T – Contravariance lets a method take parameters that are from a superclass of the type expected by a delegate.

Variance is supported by reference types only and just because a class implements one of the interfaces listed here, it doesn’t mean those types support it. For example, List<T> implements IEnumerable but is invariant.

Hope you found this helpful.

Sources/References: