例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:
if (!some condition) return;
Some code...
我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。
例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:
if (!some condition) return;
Some code...
我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。
当前回答
这里有几个很好的观点,但如果方法非常冗长,多个返回点也可能是不可读的。也就是说,如果你打算使用多个返回点,只要确保你的方法是简短的,否则多个返回点的可读性奖励可能会丢失。
其他回答
我想这要看你喜欢什么了,如前所述,没有统一的意见。 为了减少麻烦,您可以将这种警告减少为“提示”。
表演分为两部分。在软件处于生产状态时,您需要性能,但在开发和调试时也需要性能。开发人员最不想做的事情就是“等待”一些微不足道的事情。最后,在启用优化的情况下编译该代码将生成类似的代码。所以知道这些在两种情况下都有好处的小技巧是很好的。
问题中的情况很清楚,ReSharper是正确的。不是嵌套if语句,也不是在代码中创建新的作用域,而是在方法的开头设置一个明确的规则。它增加了可读性,更容易维护,并减少了人们必须筛选的规则数量。
在性能方面,这两种方法之间没有明显的区别。
但是编码不仅仅关乎性能。清晰性和可维护性也非常重要。而且,在这种情况下,它不会影响性能,这是唯一重要的事情。
关于哪种方法更可取,存在着相互竞争的思想流派。
一种观点是其他人已经提到的观点:第二种方法减少了嵌套级别,从而提高了代码的清晰度。这在命令式风格中是很自然的:当你没有什么事情要做的时候,你不妨早点回来。
从函数式风格的角度来看,另一种观点认为一个方法应该只有一个出口点。函数式语言中的一切都是表达式。所以if语句必须总是有一个else子句。否则if表达式并不总是有值。所以在函数式风格中,第一种方法更自然。
避免多个退出点可以提高性能。我对c#不太确定,但在c++中,命名返回值优化(复制省略,ISO c++ '03 12.8/15)依赖于有一个单一的出口点。这种优化避免了复制构造返回值(在您的特定示例中,这无关紧要)。在紧密循环中,这可能会大大提高性能,因为每次调用函数时都保存了一个构造函数和一个析构函数。
但是在99%的情况下,节省额外的构造函数和析构函数调用并不值得损失嵌套的可读性,如果块引入(正如其他人所指出的)。
我想补充的是,这些倒置的if是有名称的-保护条款。我一有机会就用它。
我讨厌阅读一开始只有两屏代码的代码。只要求if的倒数,然后返回。这样就没人会浪费时间刷屏幕了。
http://c2.com/cgi/wiki?GuardClause