例如,当我在我的代码上运行ReSharper时:

    if (some condition)
    {
        Some code...            
    }

ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:

   if (!some condition) return;
   Some code...

我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。


当前回答

它不仅美观,而且还减少了方法内部的最大嵌套级别。这通常被认为是一个优点,因为它使方法更容易理解(事实上,许多静态分析工具提供了一种度量方法,作为代码质量的指标之一)。

另一方面,它还使您的方法具有多个退出点,另一组人认为这是不可取的。

就我个人而言,我同意ReSharper和第一组(在有例外的语言中,我发现讨论“多个退出点”是愚蠢的;几乎任何东西都可能抛出,所以在所有方法中都有许多潜在的退出点)。

关于性能:每种语言的两个版本都应该是等效的(如果不是在IL级别,那么肯定是在代码抖动结束后)。从理论上讲,这取决于编译器,但实际上,今天任何广泛使用的编译器都能够处理比这更高级的代码优化情况。

其他回答

这里已经有很多有见地的答案,但是,我仍然想要指向一个稍微不同的情况:而不是前置条件,它实际上应该放在函数的顶部,考虑一步一步的初始化,在那里你必须检查每一步是否成功,然后继续下一步。在这种情况下,您不能检查顶部的所有内容。

当我使用Steinberg的ASIOSDK编写ASIO主机应用程序时,我发现我的代码真的难以阅读,因为我遵循了嵌套范式。它有8层深,我看不出有什么设计缺陷,正如Andrew Bullock上面提到的那样。当然,我可以将一些内部代码打包到另一个函数中,然后在那里嵌套剩余的级别以使其更具可读性,但对我来说这似乎相当随机。

通过用保护子句替换嵌套,我甚至发现了自己的一个误解,即一部分清理代码应该在函数的早期出现,而不是在函数的末尾。对于嵌套分支,我从来没有看到过,你甚至可以说它们导致了我的误解。

所以这可能是另一种情况,反向if可以有助于更清晰的代码。

我想这要看你喜欢什么了,如前所述,没有统一的意见。 为了减少麻烦,您可以将这种警告减少为“提示”。

正如其他人所提到的,不应该对性能造成影响,但还有其他考虑因素。除了这些合理的担忧,在某些情况下,这也会让你陷入困境。假设你处理的是一个double:

public void myfunction(double exampleParam){
    if(exampleParam > 0){
        //Body will *not* be executed if Double.IsNan(exampleParam)
    }
}

将其与看似等效的反转进行对比:

public void myfunction(double exampleParam){
    if(exampleParam <= 0)
        return;
    //Body *will* be executed if Double.IsNan(exampleParam)
}

所以在某些情况下,看起来是正确的a颠倒的if可能不是。

这是一个有点宗教的争论,但我同意ReSharper的观点,你应该更喜欢少嵌套。我相信这超过了一个函数有多条返回路径的缺点。

减少嵌套的关键原因是为了提高代码的可读性和可维护性。请记住,将来会有许多其他开发人员需要阅读您的代码,而缩进较少的代码通常更容易阅读。

前置条件是一个很好的例子,说明在函数开始时可以提前返回。为什么函数其余部分的可读性会受到前置条件检查的影响?

至于从一个方法返回多次的缺点——现在调试器非常强大,很容易找到特定函数返回的确切位置和时间。

函数中有多个返回值并不会影响维护程序员的工作。

糟糕的代码可读性会。

我的想法是“在函数中间”的返回不应该那么“主观”。 原因很简单,以下面的代码为例:

    function do_something( data ){

      if (!is_valid_data( data )) 
            return false;


       do_something_that_take_an_hour( data );

       istance = new object_with_very_painful_constructor( data );

          if ( istance is not valid ) {
               error_message( );
                return ;

          }
       connect_to_database ( );
       get_some_other_data( );
       return;
    }

也许第一个“回报”不是那么直观,但这是真正的储蓄。 有太多关于干净代码的“想法”,只是需要更多的实践来摆脱他们“主观的”坏想法。