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

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

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

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

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


当前回答

只在函数结束时返回的想法来自语言支持异常之前的时代。它使程序能够依赖于能够将清理代码放在方法的末尾,然后确保它会被调用,而其他程序员不会在方法中隐藏导致跳过清理代码的返回值。跳过清理代码可能导致内存或资源泄漏。

然而,在支持异常的语言中,它不提供这样的保证。在支持异常的语言中,任何语句或表达式的执行都可能导致导致方法结束的控制流。这意味着清理必须通过使用finally或使用关键字来完成。

不管怎样,我想说的是,我认为很多人引用了“只在方法末尾返回”的指导原则,却不理解为什么它是一件好事,而减少嵌套以提高可读性可能是一个更好的目标。

其他回答

它不仅影响美观,而且还阻止了代码嵌套。

它实际上也可以作为确保数据有效的前提条件。

从理论上讲,反转if可以提高分支预测的命中率,从而提高性能。在实践中,我认为很难确切地知道分支预测将如何表现,特别是在编译之后,所以我不会在日常开发中这样做,除非我正在编写汇编代码。

更多关于分支预测的信息。

这里有几个很好的观点,但如果方法非常冗长,多个返回点也可能是不可读的。也就是说,如果你打算使用多个返回点,只要确保你的方法是简短的,否则多个返回点的可读性奖励可能会丢失。

表演分为两部分。在软件处于生产状态时,您需要性能,但在开发和调试时也需要性能。开发人员最不想做的事情就是“等待”一些微不足道的事情。最后,在启用优化的情况下编译该代码将生成类似的代码。所以知道这些在两种情况下都有好处的小技巧是很好的。

问题中的情况很清楚,ReSharper是正确的。不是嵌套if语句,也不是在代码中创建新的作用域,而是在方法的开头设置一个明确的规则。它增加了可读性,更容易维护,并减少了人们必须筛选的规则数量。

避免多个退出点可以提高性能。我对c#不太确定,但在c++中,命名返回值优化(复制省略,ISO c++ '03 12.8/15)依赖于有一个单一的出口点。这种优化避免了复制构造返回值(在您的特定示例中,这无关紧要)。在紧密循环中,这可能会大大提高性能,因为每次调用函数时都保存了一个构造函数和一个析构函数。

但是在99%的情况下,节省额外的构造函数和析构函数调用并不值得损失嵌套的可读性,如果块引入(正如其他人所指出的)。