【问题标题】:How do I refactor multiple similar methods of this sort into a single method?如何将多个此类类似的方法重构为一个方法?
【发布时间】:2009-04-13 20:00:53
【问题描述】:

假设我有许多相关的类都有这样的方法:

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

constructorParm的类型可能会改变(也可能是staticSetting),具体的属性肯定会改变,但属性的类型永远是bool

进一步假设我已经决定让 8 个不同的类在实现级别上做完全相同的事情是很愚蠢的——切换一个布尔值。尤其是当它们在语义层面上也都相关时(它们都派生自同一个 Command 抽象基类,这是 OnExecute() 的来源)。

如何在不参数化实际切换操作本身的情况下参数化要切换的属性?例如,我知道我可以做这样的事情(未编译):

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;});

但是我怎样才能在类中捕获切换行为,同时仍接受可写属性作为参数呢? (如果我将切换作为参数传递,那么我只是在制作一个过于复杂的委托。)

(我不能只传递 b/c 中的属性 bool 是一个值类型,所以我只是切换一个副本。我不能通过 ref 传递它,当然,b/c属性不能通过 ref 传递。我觉得一定有一些愚蠢而明显的东西,我在这里真的很想念。:))

上下文

我之所以以间接的方式做这么简单的事情,实际上是由于在winforms中使用了GoF命令模式。 Commands 的核心功能更复杂,但Commands 的这个小子集本质上只是切换一个属性,该属性将在其他地方引发 PropertyChanged 事件。我不想将所有这些命令放在单独的类中,而是将它们合并为一个,因为它们非常简单。

【问题讨论】:

  • 你不能很好地重构这种东西。您需要良好的元编程工具(即宏)。

标签: c# refactoring properties


【解决方案1】:

您可以通过 PropertyInfo 类使用反射来选择要切换的属性:

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);

您只需保留要切换的属性的名称。

但是,这只有在“切换属性”成为您设计的明确部分时才有意义。否则,当“简单”的解决方案是正常切换属性时,对于这种基本的东西来说肯定是矫枉过正。

【讨论】:

    【解决方案2】:

    您可能可以使用反射来指定要更改的属性,但是如果选项数量有限(您提到有 8 个类),我建议您使用 switch 语句,并在类构造函数。

    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;
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      这里有一些很好的答案

      恐怕我不是这些方面的专家。但我认为情况相似。

      Can you refactor out a common functionality from these two methods?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-16
        • 2015-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 2017-11-29
        相关资源
        最近更新 更多