views:

147

answers:

3

Suppose I have a number of related classes that all have a method like this:

protected override OnExecute()
{
    this.constructorParm.BoolProperty = !this.constructorParm.BoolProperty;
}

The type of constructorParm may change (it may also be a static Setting), and the specific property will certainly change, but the type of the property will always be bool.

Suppose further that I've decided it's silly to have 8 different classes that all do the exact same thing on an implementation level- toggle a bool value. Especially when they're all related on a semantic level also (they all derive from the same Command abstract base class, which is where OnExecute() comes from).

How to I parameterize the property that I want to toggle without parameterizing the actual toggle operation itself? For example, I know I can do something like this (uncompiled):

internal class CommandX
{
    Action doExecute = null;
    public CommandX(Action executeAction) { this.doExecute = executeAction; }
    protected override OnExecute() { this.doExecute(); }
}

// elsewhere
var b = new CommandX(() => {target.BoolProperty = !target.BoolProperty;});

but how I can I capture the toggling behavior in the class, while still accepting the writable property as a parameter? (If I pass the toggling in as a parameter, then I'm just making an over-complicated delegate.)

(I can't just pass the property in b/c bool is a value type, so I'd just be toggling a copy. I can't pass it in by ref, of course, b/c properties can't be passed by ref. I feel like there's got to be something stupid and obvious that I'm just really missing here. :) )

Context

The reason I'm doing such a simple thing in an indirect manner is actually due to the use of the GoF Command pattern in winforms. The core functionality Commands are more complex, but this small subset of Commands essentially just toggles a property that will raise PropertyChanged events elsewhere. Instead of having all these commands in separate classes, I wanted to fold them into one because they're so simple.

+2  A: 

You could use Reflection to select which property to toggle by using the PropertyInfo class:

string propertyName = "BoolProperty";
Foo myFoo = new Foo();
Type myFooType = myFoo.GetType();
PropertyInfo prop = myFooType.GetProperty(propertyName);
prop.SetValue(myFoo, !((bool)prop.GetValue(myFoo, null)), null);

You'd only have to keep the name of the property that you'd like to toggle.

However, this would only make sense if "toggling a property" makes explicit part of your design. Otherwise, it would definately be overkill for something this basic when the "easy" solution is to just toggle the property normally.

Ilia Jerebtsov
A: 

You could probably make use of reflection to specify what property to change, but if there are a limited number of options (you mention there are 8 classes), I would recommend that you use a switch statement, and have an enumeration in the class constructor.

internal enum PropertyOption { Prop1, Prop2 }

internal class Bar {
  PropertyOptiion prop;
  public Bar(PropertyOption prop) {
    this.prop = prop;
  }
  public override OnFoo() {
    switch (prop) {
      case PropertyOption.Prop1:
        this.prop1 = !this.prop1;
        break;
      case PropertyOption.Prop2:
        this.prop2 = !this.prop2;
        break;
    }
  }
}
YotaXP
A: 

Some good answers here

I'm afraid I'm not an expert on any of these. But I think the situations are similar.

http://stackoverflow.com/questions/735473/can-you-refactor-out-a-common-functionality-from-these-two-methods