C# 反转“if”语句以减少嵌套
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/268132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Invert "if" statement to reduce nesting
提问by Lea Cohen
When I ran ReSharperon my code, for example:
例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper gave me the above warning (Invert "if" statement to reduce nesting), and suggested the following correction:
ReSharper 给了我上述警告(反转“if”语句以减少嵌套),并建议进行以下更正:
if (!some condition) return;
Some code...
I would like to understand why that's better. I always thought that using "return" in the middle of a method problematic, somewhat like "goto".
我想了解为什么这样更好。我一直认为在方法中间使用“return”有问题,有点像“goto”。
采纳答案by jop
A return in the middle of the method is not necessarily bad. It might be better to return immediately if it makes the intent of the code clearer. For example:
方法中间的返回不一定是坏的。如果能让代码的意图更清晰,最好立即返回。例如:
double getPayAmount() {
double result;
if (_isDead) result = deadAmount();
else {
if (_isSeparated) result = separatedAmount();
else {
if (_isRetired) result = retiredAmount();
else result = normalPayAmount();
};
}
return result;
};
In this case, if _isDead
is true, we can immediately get out of the method. It might be better to structure it this way instead:
在这种情况下,如果_isDead
为真,我们可以立即退出该方法。以这种方式构建它可能会更好:
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
I've picked this code from the refactoring catalog. This specific refactoring is called: Replace Nested Conditional with Guard Clauses.
我从重构目录中挑选了这段代码。这种特定的重构称为:用保护子句替换嵌套条件。
回答by unwind
That is simply controversial. There is no "agreement among programmers" on the question of early return. It's always subjective, as far as I know.
这简直是有争议的。关于提前返回的问题,没有“程序员之间的协议”。据我所知,这总是主观的。
It's possible to make a performance argument, since it's better to have conditions that are written so they are most often true; it can also be argued that it is clearer. It does, on the other hand, create nested tests.
可以进行性能论证,因为最好编写条件,以便它们通常为真;也可以说它更清楚。另一方面,它确实创建了嵌套测试。
I don't think you will get a conclusive answer to this question.
我不认为你会得到这个问题的决定性答案。
回答by Colin Pickard
It's a matter of opinion.
这是一个意见问题。
My normal approach would be to avoid single line ifs, and returns in the middle of a method.
我通常的方法是避免单行 ifs,并在方法中间返回。
You wouldn't want lines like it suggests everywhere in your method but there is something to be said for checking a bunch of assumptions at the top of your method, and only doing your actual work if they all pass.
您不希望在您的方法中随处可见这样的行,但是在检查方法顶部的一堆假设时需要说一些话,并且只有在它们全部通过时才执行您的实际工作。
回答by LeopardSkinPillBoxHat
This is a bit of a religious argument, but I agree with ReSharper that you should prefer less nesting. I believe that this outweighs the negatives of having multiple return paths from a function.
这有点宗教性的论点,但我同意 ReSharper 的观点,即您应该更喜欢减少嵌套。我相信这超过了从函数中获得多个返回路径的负面影响。
The key reason for having less nesting is to improve code readability and maintainability. Remember that many other developers will need to read your code in the future, and code with less indentation is generally much easier to read.
减少嵌套的关键原因是提高代码的可读性和可维护性。请记住,许多其他开发人员将来需要阅读您的代码,而缩进较少的代码通常更容易阅读。
Preconditionsare a great example of where it is okay to return early at the start of the function. Why should the readability of the rest of the function be affected by the presence of a precondition check?
先决条件是一个很好的例子,说明可以在函数开始时提前返回。为什么存在前提条件检查会影响函数其余部分的可读性?
As for the negatives about returning multiple times from a method - debuggers are pretty powerful now, and it's very easy to find out exactly where and when a particular function is returning.
至于从一个方法多次返回的负面影响 - 调试器现在非常强大,而且很容易找出特定函数返回的确切位置和时间。
Having multiple returns in a function is not going to affect the maintainance programmer's job.
在一个函数中有多个返回不会影响维护程序员的工作。
Poor code readability will.
代码可读性差会。
回答by Bluenuance
I think it depends on what you prefer, as mentioned, theres no general agreement afaik. To reduce annoyment, you may reduce this kind of warning to "Hint"
我认为这取决于你喜欢什么,如上所述,没有普遍的协议 afaik。为了减少烦恼,您可以将此类警告减少为“提示”
回答by Deestan
This is of course subjective, but I think it strongly improves on two points:
这当然是主观的,但我认为它在两点上有很大的改进:
- It is now immediately obvious that your function has nothing left to do if
condition
holds. - It keeps the nesting level down. Nesting hurts readability more than you'd think.
- 现在很明显,如果
condition
成立,您的函数就无事可做。 - 它可以降低嵌套级别。嵌套对可读性的影响比你想象的要大。
回答by Oli
Guard clauses or pre-conditions (as you can probably see) check to see if a certain condition is met and then breaks the flow of the program. They're great for places where you're really only interested in one outcome of an if
statement. So rather than say:
保护子句或前置条件(如您所见)检查是否满足特定条件,然后中断程序流程。它们非常适合您真正只对if
声明的一个结果感兴趣的地方。所以与其说:
if (something) {
// a lot of indented code
}
You reverse the condition and break if that reversed condition is fulfilled
您反转条件并在满足反转条件时中断
if (!something) return false; // or another value to show your other code the function did not execute
// all the code from before, save a lot of tabs
return
is nowhere near as dirty as goto
. It allows you to pass a value to show the rest of your code that the function couldn't run.
return
远不及goto
. 它允许您传递一个值以显示该函数无法运行的其余代码。
You'll see the best examples of where this can be applied in nested conditions:
您将看到可以在嵌套条件中应用此方法的最佳示例:
if (something) {
do-something();
if (something-else) {
do-another-thing();
} else {
do-something-else();
}
}
vs:
对比:
if (!something) return;
do-something();
if (!something-else) return do-something-else();
do-another-thing();
You'll find few people arguing the first is cleaner but of course, it's completely subjective. Some programmers like to know what conditions something is operating under by indentation, while I'd much rather keep method flow linear.
你会发现很少有人认为第一个更干净,但当然,这完全是主观的。一些程序员喜欢通过缩进来了解某些东西在什么条件下运行,而我更愿意保持方法流程的线性。
I won't suggest for one moment that precons will change your life or get you laid but you might find your code just that little bit easier to read.
我暂时不会建议 precons 会改变你的生活或让你躺下,但你可能会发现你的代码更容易阅读。
回答by Joshi Spawnbrood
My idea is that the return "in the middle of a function" shouldn't be so "subjective". The reason is quite simple, take this code:
我的想法是“在函数中间”的返回不应该那么“主观”。原因很简单,看这段代码:
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; }
Maybe the first "return" it's not SO intuitive, but that's really saving. There are too many "ideas" about clean codes, that simply need more practise to lose their "subjective" bad ideas.
也许第一个“返回”不是那么直观,但这真的很省钱。关于干净代码的“想法”太多了,只需要更多的练习就可以摆脱他们“主观”的坏想法。
回答by Scott Langham
The idea of only returning at the end of a function came back from the days before languages had support for exceptions. It enabled programs to rely on being able to put clean-up code at the end of a method, and then being sure it would be called and some other programmer wouldn't hide a return in the method that caused the cleanup code to be skipped. Skipped cleanup code could result in a memory or resource leak.
只在函数结束时返回的想法来自于语言支持异常之前的日子。它使程序能够依赖于能够在方法的末尾放置清理代码,然后确保它会被调用,并且其他一些程序员不会隐藏导致跳过清理代码的方法中的返回. 跳过清理代码可能会导致内存或资源泄漏。
However, in a language that supports exceptions, it provides no such guarantees. In a language that supports exceptions, the execution of any statement or expression can cause a control flow that causes the method to end. This means clean-up must be done through using the finally or using keywords.
然而,在支持异常的语言中,它不提供这样的保证。在支持异常的语言中,任何语句或表达式的执行都可能导致导致方法结束的控制流。这意味着必须通过使用 finally 或 using 关键字来进行清理。
Anyway, I'm saying I think a lot of people quote the 'only return at the end of a method' guideline without understanding why it was ever a good thing to do, and that reducing nesting to improve readability is probably a better aim.
无论如何,我想说的是,我认为很多人引用了“只在方法结束时返回”的指导方针,却没有理解为什么这样做是一件好事,并且减少嵌套以提高可读性可能是一个更好的目标。
回答by Richard Poole
Multiple return points were a problem in C (and to a lesser extent C++) because they forced you to duplicate clean-up code before each of the return points. With garbage collection, the try
| finally
construct and using
blocks, there's really no reason why you should be afraid of them.
多个返回点在 C(以及在较小程度上是 C++)中是一个问题,因为它们迫使您在每个返回点之前复制清理代码。有了垃圾收集,try
| finally
构造和using
块,你真的没有理由害怕它们。
Ultimately it comes down to what you and your colleagues find easier to read.
最终归结为您和您的同事认为更容易阅读的内容。