Dependency Properties

Dependency properties are a special feature of WPF that is similar in principal to regular .NET properties, with at least two functional distinctions:

  • They support change notifications
  • They support special handling for animations, retaining the “original” value

The problem with dependency properties is that they are not directly supported by C# language, and the syntax is quite verbose. Here’s how a typical dependency property is defined in a class that ultimately derives from DependencyObject:

        public static readonly DependencyProperty CenterProperty =
            DependencyProperty.Register("Center", typeof(Point3D), typeof(Sphere),
                new PropertyMetadata(new Point3D(0, 0, 0), CenterChanged));

        public Point3D Center
        {
            get { return (Point3D)GetValue(CenterProperty); }
            set { SetValue(CenterProperty, value); }
        }

        private static void OnCenterChanged(Object sender, DependencyPropertyChangedEventArgs e)
        {
            Sphere s = ((Sphere)sender);
            s.DoUpdateWhenCenterChanges();
        }

That’s a lot of code. It is verbose, it is not type safe (note all the type casts), and it brings us back to the days of object oriented programming in C, when everything is static and you need to pass this pointer around. Also, retrieving dependency properties is (allegedly) slow, so in tight loops you should cache them:

Point3D center = Center;
foreach (var item in BigCollection)
{
    // use center, not Center
}

Demanding that C# directly supported dependency properties would be silly: you cannot just throw features into the language just like that. What would be nice is some kind of intelligent macro mechanism that would generate the boilerplate code for you, so you could just write something like

[DependencyProperty]
Point3D Center { get; set; }

It is possible to ease the pain somewhat by using helper templates, but the syntax does not come even close to the ideal above. The property is defined by three main pieces of information:

  • Property type
  • Containing type
  • Property name

While first two may be made into template parameters (think PropertyHolder<Point3D,Sphere>), the third one cannot – unlike C++, in C# strings cannot be template parameters. So, even with templates we cannot go far. This is not the only case that makes me wish C# had some kind of macro expansion mechanism, but this is quite a typical one. Of course, we would not want something as dangerous as C macros, we probably want something closer to LISP macros, but we definitely need something.

Posted in

Leave a Reply

Your email address will not be published. Required fields are marked *