Properties as objects
I was thinking about two items from Object Thinking:
- Everything is an object.
- Every object should provide events for when its attributes change.
There's the idea that objects can collaborate without top-down control, if they provide & register events with each other.
My first reaction to #2 is that it violates YAGNI. But in the interest of extremism, I'll let it ride for now.
The standard way to do #2 is something like:
class Customer
{
int _age;
public int Age
{
get {
return this._age;
}
private set
{
this._age = value;
this.Age_OnChange(this, null);
}
}
public event System.EventHandler Age_OnChange;
}
Now, you already know how much I love properties. I’m annoyed when I read this code, because I use 15 lines of text to express what should be a very basic idea.
There’s also a bunch of smelly duplication. Not only does the word “age” appear 6 times, but 2 of them are carefully concealed in a bigger name (“Age_OnChange”), which is quite easy to miss in later code changes. Yuck.
So, what if we apply #1? What if we make an object that represents a property? It would look like:
class Property<T>
{
public Property(T t) { ... }
public event System.EventHandler OnChanged;
public T Value { ... }
}
Well, I tried to implement it, and ran into some problems. The biggest is that I can’t state who has permissions to set the property. With the seed code above, only the containing class has write access to the value.
Here’s the best I came up with:
class Property<T>
{
private T _value;
public event System.EventHandler OnChanged;
public T Value
{
get { return this._value; }
set
{
this._value = value;
this.OnChanged(this, null);
}
}
}
class Customer
{
public Property<int> age = new Property<int>();
static void Main(string[] args)
{
Customer customer = new Customer();
customer.age.OnChanged += delegate { Console.WriteLine("age changed"); };
customer.age.Value = 9;
}
}
I don’t think I can do any better. Got any ideas?