例如,当我在我的代码上运行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”。
当前回答
这里有几个很好的观点,但如果方法非常冗长,多个返回点也可能是不可读的。也就是说,如果你打算使用多个返回点,只要确保你的方法是简短的,否则多个返回点的可读性奖励可能会丢失。
其他回答
关于代码的外观有很多很好的理由。但是结果如何呢?
让我们来看看一些c#代码和它的IL编译形式:
using System;
public class Test {
public static void Main(string[] args) {
if (args.Length == 0) return;
if ((args.Length+2)/3 == 5) return;
Console.WriteLine("hey!!!");
}
}
可以编译这个简单的代码片段。您可以使用ildasm打开生成的.exe文件并检查结果。我不会发布所有汇编程序的东西,但我会描述结果。
生成的IL代码执行以下操作:
如果第一个条件为假,则跳转到第二个条件所在的代码。 如果为真,则跳转到最后一条指令。(注意:最后一个指令是return)。 在第二种情况下,计算结果后也会发生同样的情况。比较和:到达控制台。如果为假则写eline,如果为真则写到结尾。 打印消息并返回。
所以看起来代码会跳到最后。如果我们对嵌套代码做一个正常的if呢?
using System;
public class Test {
public static void Main(string[] args) {
if (args.Length != 0 && (args.Length+2)/3 != 5)
{
Console.WriteLine("hey!!!");
}
}
}
结果在IL指令中非常相似。不同之处在于,之前每个条件有两次跳转:如果为假则跳转到下一段代码,如果为真则跳转到最后一段代码。现在IL代码流得更好了,有3个跳跃(编译器优化了一点):
第一次跳转:当Length为0到代码再次跳转(第三次跳转)的部分时。 第二:在第二种情况中间避免一条指令。 第三:如果第二个条件为假,跳到最后。
不管怎样,程序计数器总是会跳转。
There are several advantages to this sort of coding but for me the big win is, if you can return quick you can improve the speed of your application. IE I know that because of Precondition X that I can return quickly with an error. This gets rid of the error cases first and reduces the complexity of your code. In a lot of cases because the cpu pipeline can be now be cleaner it can stop pipeline crashes or switches. Secondly if you are in a loop, breaking or returning out quickly can save you a lots of cpu. Some programmers use loop invariants to do this sort of quick exit but in this you can broke your cpu pipeline and even create memory seek problem and mean the the cpu needs to load from outside cache. But basically I think you should do what you intended, that is end the loop or function not create a complex code path just to implement some abstract notion of correct code. If the only tool you have is a hammer then everything looks like a nail.
表演分为两部分。在软件处于生产状态时,您需要性能,但在开发和调试时也需要性能。开发人员最不想做的事情就是“等待”一些微不足道的事情。最后,在启用优化的情况下编译该代码将生成类似的代码。所以知道这些在两种情况下都有好处的小技巧是很好的。
问题中的情况很清楚,ReSharper是正确的。不是嵌套if语句,也不是在代码中创建新的作用域,而是在方法的开头设置一个明确的规则。它增加了可读性,更容易维护,并减少了人们必须筛选的规则数量。
这是意见的问题。
我通常的方法是避免单行if,并在方法中间返回。
你不希望在你的方法中到处都是这样的行,但是在你的方法顶部检查一堆假设是有意义的,只有在它们都通过时才做实际的工作。
它不仅影响美观,而且还阻止了代码嵌套。
它实际上也可以作为确保数据有效的前提条件。