Generalized Properties in C#

We’re all familiar with properties in C#.  Objects can have properties, property values can be got and set, and you can run code when they are got or set.  Simple, powerful, used all the time.

But they have a weakness.  Unless you get into the messy business of reflection, the compiler has to know at compile-time how you’re going to use the properties.  What do I mean by that?  I mean that to use a property on an object, you need to have a reference to that object, you need to know the type of that object, and your code needs to know both the name and type of the property.  The compiler needs to be able to resolve the whole usage.

Okay, but what if you need to make decisions about how to get or set properties at run-time?  Imagine you have a component that needs to do work on properties from a lot of different sources.  Let’s say it only knows the type of the properties and knows it needs to set them, but shouldn’t know about the parent objects or the real name of the properties?

What do we need?  Generalized properties!

Okay, so let’s distill a property down to it’s most basic form.  It has a value.  You can get that value.  You can set that value.  For simplicity’s sake and for now, let’s say we don’t even need to know the type of the value.  We’d like it to be easily portable.  BAM, let’s make it an object:

/// <summary>
    /// A PropertyProxy is an object that behaves like a property.  It has a Value that you can get or set.
    /// It can be databound to, allowing databinding decisions to be made at run-time.
    /// </summary>
    public abstract class PropertyProxy
    {
        public object Value
        {
            get
            {
                return this.getValue();
            }
            set
            {
                this.setValue(value);
            }
        }

        protected abstract object getValue();
        protected abstract void setValue(object value);
    }

This is the abstract base class.  In actual usage, we’d subclass it and provide a specific implementation for getValue and setValue.  Now we can instantiate one of these and pass it around, and client code doesn’t need to know about what’s actually happening when you get or set the value.

Other advantages:

– Complex databinding decisions can be made at run-time.

– It can be used to protect our data objects from meddling.  They have control over how they are used.

– We can run arbitrary code in getValue and setValue.  They don’t actually HAVE TO hook up to the getters and setters of real C# properties.  Imagine hooking setValue up to an Undo/Redo system.

Next time I’ll talk about how the PropertyProxy can be extended, and the real reason why we built it.  Why would we need to generalize properties?  I’ll let you sit with that.

  1. No trackbacks yet.

Leave a comment