拥有终止子句时的最佳做法是什么...请参阅说明:)

时间:2020-03-06 14:50:36  来源:igfitidea点击:

情况如下:
我们有一个名为FullScreenEnabled的布尔属性。我们输入一些方法,并且当FullScreenEnabled为true时,将执行此方法中的代码。我们在日常编程中使用以下两种方法中的哪一种:

private bool FullScreenEnabled { get; set; }
    // Check if FullScreenEnabled is false and return;
    private void Case1()
    {
        if (FullScreenEnabled == false)
        {
            return;
        }

        // code to be executed goes here!
    }

    // Surround the code by an if statement.
    private void Case2()
    {
        if (FullScreenEnabled)
        {
            // code to be executed goes here!
        }
    }

解决方案

两种方法均未发布。我们应该阅读编辑帮助,以确保代码实际出现。

private void MyMethod(bool arg){
   if(arg)
       return;
   //do stuff
};

(投票)

private void MyMethod(bool arg){
    if(!arg){
        //do stuff
    }
}

(投票)

我通常更喜欢第一个版本(在方法开始时进行保全)。它导致更少的嵌套,从而稍微增加了可读性。如果我们决定以后不再需要检查条件,则在第一个版本中删除if条件也将更加容易,尤其是当我们进行多次检查时。另外,它可以很容易地用一行编写:if(!FullScreenEnabled)return;

这取决于方法的长度和复杂性。如果该方法很短,则在if中嵌套是没有问题的(并且可能会更清楚)。如果该方法具有许多嵌套语句,则立即返回将减少必要的缩进量,并可能会稍微提高可读性。

这是关于应该测试是肯定的还是否定的,即,如果不满足条件,则从方法开始处返回,或者仅当满足条件时才执行代码。在短方法中,我会选择后一种情况;在长方法中,我会选择前一种情况。当要测试多个条件时,我总是会选择提前退出。但这并没有真正的改变。

但是请注意,在示例中是与false的比较。我们应该改写!FullScreenEnabled。使代码更具可读性。

if (!FullScreenEnabled)
    throw new InvalidOperationException("Must be in fullscreen mode to do foo.");

我的两分钱,这是值得的。

两种方法都相同。

但是,如果我们为单元测试运行代码覆盖率指标,则if(!FullScreenEnabled)return;将被计为一个单独的块,我们必须创建一个单元测试来覆盖它以达到100%。

当然,即使使用其他方法,我们也可能希望进行单元测试,以验证FullScreenEnabled为false时是否未执行代码。但是,如果我们作弊并且不写,我们仍然会得到100%的收益。 :-)

如果添加案例,则第一种方法(使用保护子句)可以更好地扩展。第二种方法的问题是,添加更多的if语句将导致代码呈现出箭头反模式,其中代码开始像箭头一样被识别。

下面有一篇非常好的文章对此进行了更详细的说明:

编码恐怖:扁平化箭头代码

我会采用第一种方法,我发现它比第二种方法更具可读性。
基本上我认为:

  • if(FullScreenEnabled == false)比if(FullScreenEnabled)更具可读性。
  • 如果我们始终将"健全性"检查放在方法的开头,则该方法将获得一个很好的结构,该结构非常易于理解。

但是我认为这里有一条细线是不需要越过的,将" return"语句放在方法中间的太多地方确实会使它变得更复杂