例如,当我在我的代码上运行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”。
当前回答
我不确定,但我认为,r#试图避免远跳。当你有IF-ELSE时,编译器会做这样的事情:
条件false ->远跳到false_condition_label
true_condition_label: instruction1 ... instruction_n
false_condition_label: instruction1 ... instruction_n
结束块
如果condition为真,则没有跳转,也没有L1缓存的滚出,但是跳转到false_condition_label可能很远,处理器必须滚出自己的缓存。同步缓存的开销很大。r#尝试将远跳转替换为短跳转,在这种情况下有更大的概率,所有指令都已经在缓存中。
其他回答
就我个人而言,我倾向于只有一个退出点。如果您保持方法的简短和切中要害,这很容易实现,并且它为下一个处理您的代码的人提供了可预测的模式。
eg.
bool PerformDefaultOperation()
{
bool succeeded = false;
DataStructure defaultParameters;
if ((defaultParameters = this.GetApplicationDefaults()) != null)
{
succeeded = this.DoSomething(defaultParameters);
}
return succeeded;
}
如果您只是想在函数退出之前检查函数中某些局部变量的值,这也是非常有用的。您所需要做的就是在最终返回值上放置一个断点,并保证能够命中它(除非抛出异常)。
我想补充的是,这些倒置的if是有名称的-保护条款。我一有机会就用它。
我讨厌阅读一开始只有两屏代码的代码。只要求if的倒数,然后返回。这样就没人会浪费时间刷屏幕了。
http://c2.com/cgi/wiki?GuardClause
从理论上讲,反转if可以提高分支预测的命中率,从而提高性能。在实践中,我认为很难确切地知道分支预测将如何表现,特别是在编译之后,所以我不会在日常开发中这样做,除非我正在编写汇编代码。
更多关于分支预测的信息。
我想这要看你喜欢什么了,如前所述,没有统一的意见。 为了减少麻烦,您可以将这种警告减少为“提示”。
这是一个有点宗教的争论,但我同意ReSharper的观点,你应该更喜欢少嵌套。我相信这超过了一个函数有多条返回路径的缺点。
减少嵌套的关键原因是为了提高代码的可读性和可维护性。请记住,将来会有许多其他开发人员需要阅读您的代码,而缩进较少的代码通常更容易阅读。
前置条件是一个很好的例子,说明在函数开始时可以提前返回。为什么函数其余部分的可读性会受到前置条件检查的影响?
至于从一个方法返回多次的缺点——现在调试器非常强大,很容易找到特定函数返回的确切位置和时间。
函数中有多个返回值并不会影响维护程序员的工作。
糟糕的代码可读性会。