March 29, 2009

Implementing INotifyPropertyChanged without hard-coded strings

If you are programming with the Windows Presentation Foundation you probably also use data binding and the INotifyPropertyChanged interface. By implementing it, objects can notify controls about changed data. A typical implementation looks like this:

using System.ComponentModel;

public class NotifyPropertyExample : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };

internal void FireNotifyPropertyChanged(string propertyName)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

private string example;
public string Example
{
get { return this.example; }
set
{
this.example = value;
FireNotifyPropertyChanged("Example");
}
}
}

The interface INotifyPropertyChanged defines a single event, which takes the name of the changed property as a parameter. In the example the event is fired in the setter method of the property, passing the name of the property as string.

This works. But there are a few drawbacks here:
  • There is no auto-completion for the property name string. You have to type it.
  • The compiler cannot validate that you typed the string correctly.
  • Even during run-time a typo usually remains unnoticed. If you don't take special actions there are no exceptions thrown.
  • Code may break on refactorings. When you rename the property you have to take care the string is changed too.
Therefore implementing INotifyPropertyChanged this way can lead bugs. Nasty bugs, as they are really hard to track down.

So what to do instead?

A common way to tackle this problem (see e.g. here or here) is to use Linq expressions. Here is what I do in my code:

using System.ComponentModel;
using System.Linq.Expressions;

public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };

internal void InternalFireNotifyPropertyChanged(string propertyName)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

public static class NotifyPropertyChangedBaseExtensions
{
public static void FireNotifyPropertyChanged<T, R>(this T obj,
Expression<Func<T, R>> expr)
where T : NotifyPropertyChangedBase
{
obj.InternalFireNotifyPropertyChanged(((MemberExpression)expr.Body).Member.Name);
}
}
First I create a base class that implements INotifyPropertyChanged. Nothing special with that. The magic kicks in with the extension method FireNotifyPropertyChanged. It extends NotifyPropertyChangedBase or a derived class and takes a Linq expression as a parameter.

This looks complicated but is straight forward to use. The example above can be rewritten as follows:

public class NotifyPropertyExample2 : NotifyPropertyChangedBase
{
private string example;
public string Example
{
get { return this.example; }
set
{
this.example = value;
this.FireNotifyPropertyChanged(o => o.Example);
}
}
}
FireNotifyPropertyChanged has to be implemented as an extension method (rather than doing it in the base class) as the expression has to use your derived class to know about its properties. This way also IntelliSense works nicely.

Any disadvantages doing it this way? Yes, there is a small performance hit. An extra method call and building up the expression. So for objects whose updates are performance critical I would test if this is a problem. But for most use cases I would say that the advantages clearly weigh more heavily.

March 27, 2009

A C# implementation of the Ruby 'each' iterator

If you ever had a look at Ruby you probably saw things like the following in one of the many tutorials:


s1 = 0
(10...20).each { |x| s1 += x*x }
puts s1

s2 = 0
[3, 7, 9].each { |x| s2 += x*x }
puts s2

Really cool. First thing I loved straight away is the easy notation for ranges.
And then, of course, there's the each iterator which takes a block as parameter. Simply fantastic.

As a software developer who uses C# for most of his tasks at the moment, I was jealous. But then I thought: why just not do the same thing in C#?

Well, of course there is no fancy tripe-dot range notation is C#. But we can do it like this:

class Range
{
public static IEnumerable<int> FromTo(int from, int to)
{
int pos = from;
while (pos <= to)
{
yield return pos;
pos++;
}
}
}

Pretty easy to do with the help of the yield keyword.
OK, and what about each? You can implement that using a extension method:


static class IteratorExtensions
{

public static void Each<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
{
action(item);
}
}
}

This defines a new method Each for IEnumerable<> types. It takes a parameter of type Action, which is a void method with one parameter of type T. Action is defined in the System namespace.
Now let's take Range.FromTo and Each together and we rewrite the above Ruby script in C#:



int s1 = 0;
Range.FromTo(10,20).Each(
delegate(int x)
{
s1 += x*x;
});

Hmm, that is nowhere near the simple notation of the Ruby script...
But wait. Instead of using an anonymous method we also can used a lambda construct. Let's try it on the second part of the Ruby script:



int s2 = 0;
new[] { 3, 7, 9 }.Each(x => s2 += x*x);


Much better! Actually it almost looks like the Ruby script.
Conclusion: Ruby is nice, but C# isn't too bad either... ;-)

March 26, 2009

Using 'yield' in C#

One nice feature of C# which I wasn't aware of for a long time (sometimes it would pay off to have read a proper C# book cover to cover....) is the yield keyword. It is a very nice way to implement enumerators.

Lets look at an example, which prints out the well known Fibonacci numbers up to 1000:


class Fibonacci
{
public static IEnumerable<int> GetUpTo(int max)
{
int a = 0;
int b = 1;

yield return a;
yield return b;

while (true)
{
int next = a + b;

if (next >= max)
yield break;

yield return next;
a = b;
b = next;
}
}

static void Main()
{
foreach (var x in Fibonacci.GetUpTo(1000))
{
Console.WriteLine(x);
}
}
}


yield can be used only as yield return (which adds a new item to the enumeration) and yield break, which stops the enumeration.

The example could also be written without yield break which makes it a bit nicer:


public static IEnumerable<int> GetUpTo(int max)
{
int a = 0;
int b = 1;

yield return a;

while (b < max)
{
yield return b;

int next = a + b;
a = b;
b = next;
}
}

Without yield one would need to write a class to implement the iterator and maintain the loop state from one call to the next. Much nicer with yield. Okay, for this example you wouldn't really need an iterator in the first place but I hope the point came across...