【问题标题】:A better solution for excluding code?排除代码的更好解决方案?
【发布时间】:2013-04-30 01:52:32
【问题描述】:

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

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

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

问题是我们收到了无法访问代码的警告,所以我正在考虑用预处理器 #if/#else 替换标准 if/else 块。

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

我现在面临的问题是预处理器符号不能设置为 false,它只能定义或未定义。从以下位置更改会更明显:

#define DisplayAverageValues true

#define DisplayAverageValues false

而不是

#undef DisplayAverageValues

//#define DisplayAverageValues

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

有没有更好的办法?

【问题讨论】:

  • 预处理器选项听起来最好的 IMO。评论define 行还不错。只需整理好所有defines 的写作位置即可。
  • 我不确定#define 的问题?看起来不错的海事组织。
  • 标准方法是使用#if SYMBOL ... #endif,然后在您的项目设置中定义(或不​​定义)SYMBOL(因此不涉及评论。)
  • 我会尝试将这些不同的部分提取到基于配置设置动态加载的strategies 中。这将完全接受快速变化的需求,而不是试图解决它们。
  • 选项 #2:编码之前明确要求 :)(哦,在你做的时候要一匹小马。)

标签: c# c-preprocessor


【解决方案1】:

如果您的代码架构中有精确切片,当一个代码必须是可编译的并且不与另一个代码相交时,预处理器指令非常有用。在您的情况下,您似乎面临不同的选项,这些选项也可能在代码执行流程中与需求相交。

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

Daniel 说的另一种选择是将代码提取到不同的模块、插件中(如果您愿意),然后动态加载它们。但它可能实现,也可能不实现,顺便说一下,如果之前在您的架构中没有考虑过,您通常需要花费不相关的时间来实现这种级别的灵活性。

【讨论】:

    【解决方案2】:

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

    #if true
      // Display average values
      ...
    #else
      // Do not display average values
      ...
    #endif
    

    【讨论】:

      【解决方案3】:

      处理器指令似乎不是为这种情况设计的。从 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();
      

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

      【讨论】:

      • 这是一个很好的答案,但您仍然会收到无法访问代码的警告。
      • 抱歉,警告是什么意思?这只是快速的代码 sn-p,只是一个想法。
      • 原发帖人说:'问题是我们收到了无法访问代码的警告'。即使设计更好,您的解决方案仍然会出现这种情况(因为它无法绕过const bool DisplayAverageValues = true)。
      猜你喜欢
      • 2012-04-06
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      • 2011-11-21
      相关资源
      最近更新 更多