【问题标题】:How to handle "simple" magic values?如何处理“简单”的魔法值?
【发布时间】:2011-10-16 18:16:31
【问题描述】:

我认为这是相当独立于语言的,但如果我错了,那就选择 C#(或 C 或 C++)。

对于“简单”的魔法值,我的意思是这样的:

if (Value > 0)

while (Value < 0)

while (MyQueue > 0)

在写这个(上面的伪代码)时,我有点震惊,它真的只适用于与 0 比较的东西。

无论如何,处理这些神奇值的最佳方法是什么(考虑到可读性、要创建的击键/代码数量和命名)?

将整个(静态)类(或 C# 中的枚举)专门用于此,感觉像是极端的矫枉过正。

【问题讨论】:

  • 幻数不是要输入多少个字符,而是它们的含义——它们在上下文中是否明显且恒定。
  • 取决于这些幻数是否改变。一个例子:如果要检查队列是否为空,并且将队列长度与0进行比较,则不必封装0,因为空队列的长度始终为0。可以调整的参数值应该包含在里面一个枚举/类等。如果您有一些复杂的条件,例如“如果队列中没有红色项目,则队列为空”,请编写一个辅助函数,如 isEmpty(MyQueue)
  • 是的,正如我所写,它真的只适用于当你将某些东西(比如队列!)与 0 进行比较时,检查列表/等中的长度/对象。
  • @delnan 我确实写过“可读性”,至少在我的世界里,它会受到你所写内容的影响 :)

标签: magic-numbers magic-string


【解决方案1】:

某些数字仅在其上下文中被视为“幻数”。有些用法体现了一个简单的概念,与数字的具体值无关。例如,如果您想检查列表是否为空,您可以编写以下语句之一:

if (list.Count != 0)

if (list.Count > 0)

if (list.Count >= 1)

01 都没有任何超出“无”和“某物”的含义,因此上述三个陈述应理解为“不是没有”、“多于没有”和“至少有一些”,因此我不会称他们的用法为“幻数”。可能有其他方法可以在不使用任何数字的情况下执行此类检查。例如,在 C# 中,您可以使用 Any LINQ 运算符:

if (list.Any())

我发现这更具描述性,并且使代码具有故事般的可读性。其他语言可能有其他工具来表达诸如“无”、“某物”、“空集”、“非空集”等概念。

【讨论】:

    【解决方案2】:

    正如 Allon Guralnek 所说,我还将使用 Any() 扩展方法来检查某个集合是否包含项目。您还可以编写其他扩展方法,例如

    public static class MyExtensions {
      public static bool IsNegative(this int number) {
        return number < 0;
      }
    
      public static bool IsPositive(this int number) {
        return number > 0;
      }
    }
    

    然后将你的循环或条件写成

    if (Value.IsPositive())
    while (Value.IsNegative())
    while (MyQueue.IsPositive())
    

    假设 Value 和 MyQueue 的类型为 int

    【讨论】:

    • 这其实是一个很好的利用扩展方法的方法!为你 +1 :)
    • 我实际上建议不要将代码中最简单和不可分割的部分包装到扩展方法中。任何级别的任何软件开发人员都会理解value &gt; 0,并且那里没有需要替换的幻数。这些方法只会用于添加一个仅模糊而不是澄清的附加层,并且它们会污染每个整数的 IntelliSense 列表。尽管如此,将计算属性添加到您自己的类中是非常可接受的。例如,您可以将IsEmptyHasItemsIsActive 属性等添加到您的类中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 2012-10-11
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多