How to not implement INotifyPropertyChanged

A quick search reveals that many people have tackled the problem of implementing INotifyPropertyChanged. Here are just a few:

Here's my solution: DON'T!

You do not need to implement INotifyPropertyChanged in order to do data binding. Update Controls will do it for you. It works in Winforms, in WPF, and in Silverlight.

What's the problem, anyway?
The problem that most people see with this interface is the "magic string". You have to pass the name of the property in the event args. Many of these solutions use reflection to figure out the property name for you. That solves the magic string problem.

But that's not the real problem!

The real problem is that these techniques only work with independent properties. If one property depends upon another, then these techniques fail.

Take a closer look at PConverse's solution published in Code Project. In his RegularPerson class, DisplayName depends upon both FirstName and LastName. It has no backing field. It has no setter. It is a dependent property.

Look at the extra work he has to do in NotifiablePerson to fire PropertyChanged for DisplayName. He has to explicitly write code in the setters of both FirstName and LastName. Both of these properties have to "know" that DisplayName depends upon them.

That's a backwards dependency. FirstName and LastName should not know about DisplayName; DisplayName knows about FirstName and LastName.

Compare that to the same code using Update Controls.

public class Person
{
    private string _firstName;
    private string _lastName;

    private Independent _indFirstName = new Independent();
    private Independent _indLastName = new Independent();

    public string FirstName
    {
        get { _indFirstName.OnGet(); return _firstName; }
        set { _indFirstName.OnSet(); _firstName = value; }
    }

    public string LastName
    {
        get { _indLastName.OnGet(); return _lastName; }
        set { _indLastName.OnSet(); _lastName = value; }
    }

    public string DisplayName
    {
        get { return FirstName + " " + LastName; }
    }
}

Niether FirstName nor LastName know about DisplayName. The dependencies are one-way and in the correct direction.

Maintainability is the problem
The above example is small and manageable. But imagine what happens when this application grows. Backwards dependencies get out of hand. They cross class boundaries and cause tight coupling between objects. Pretty soon the application is nothing but dependency management.

So please, stop inventing better ways to implement INotifyPropertyChanged. It's like inventing a better way to turn the the crank on the front of a Model T. There is no good way. Just don't do it.

Leave a Reply

You must be logged in to post a comment.