排除代码的更好解决方案?

时间:2013-05-06 10:15:02

标签: c# c-preprocessor

由于需求来回变化,我们在代码中使用了一些if / else块,例如:

const bool DisplayAverageValues = true;
if(DisplayAverageValue)
{
  // Do this
}
else
{
  // Do that
}

由于需求可能会再次发生变化,我们不希望删除当前未使用的代码 - 下周可能需要它。我们也不想将未使用的代码注释掉,因为我们希望它成为任何重构的一部分。只需更改布尔值即可随时编译。

问题是我们收到了无法访问代码的警告,因此我考虑用预处理器#if /#else替换标准的if / else-block。

#define DisplayAverageValues
#if DisplayAverageValue
  // Do this
#else
  // Do that
#endif

我现在面临的问题是预处理器符号不能设置为false,只能定义或未定义。改变之后会更加明显:

#define DisplayAverageValues true

#define DisplayAverageValues false

而不是

#undef DisplayAverageValues

//#define DisplayAverageValues

(如果在其他地方使用了相同的符号名称,可能会造成麻烦)。

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

如果您的代码体系结构中有presice切片,当一个代码必须可编译且不与其他代码交叉时,预处理程序dirrectives是很好的。在您的情况下,您似乎面临着不同的选项,它们也可能在代码执行流程中的需求中交叉。

在我看来,管理它的最佳方法是定义一个OptionsRuntimeConfigurations或其他任何其他类,它包含会影响应用程序运行时行为的所有属性,并传递 instance (也可能是Singletone)该类的应用程序部分必须考虑不同的执行选项。

Daniel说的另一个选择是将代码扩展到不同的模块,如果你愿意的话插件,并动态加载它们。但是它可能会或者可能不会实现,顺便说一句,如果在您的架构中没有考虑过,那么您将需要花费非无关的时间来实现这种灵活性。

答案 1 :(得分:1)

处理器指令似乎不是针对此类情况而设计的。从SOLID的角度来看,您应该执行以下操作:

1)创建一些界面:

public interface IDoingSomething {
  void Do();
}

2)创建此接口的2个实现:

public class DoingThis : IDoingSomething {
  public void Do() {
    // Do this
  }
} 

public class DoingThat : IDoingSomething {
  public void Do() {
    // Do that
  }
} 

3)在应用程序起始点的某处读取配置并决定使用哪种实现:

IDoingSomething doerSomething;

if(DisplayAverageValue) {
  doerSomething = new DoingThis();
} else {
  doerSomething = new DoingThat();
}

4)现在使用代码中的接口对象来执行某些操作:

doerSomething.Do();

这是一种策略模式,它允许您拥有多个实现,只需一个地方即可在它们之间切换,除了具有特定接口实现的类之外,不需要任何代码更改。这有利于代码维护,可伸缩性等。

答案 2 :(得分:0)

在Tigran的评论和答案中有一些很好的建议,但是现在我将继续使用一个仍然易于理解的简单解决方案。通过删除符号名称,毫无疑问如何在需要时更改代码:

#if true
  // Display average values
  ...
#else
  // Do not display average values
  ...
#endif
相关问题