C# 在 void 方法中使用 return 是不好的做法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1283325/
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
Is it bad practice to use return inside a void method?
提问by
Imagine the following code:
想象一下以下代码:
void DoThis()
{
if (!isValid) return;
DoThat();
}
void DoThat() {
Console.WriteLine("DoThat()");
}
Is it OK to use a return inside a void method? Does it have any performance penalty? Or it would be better to write a code like this:
在 void 方法中使用 return 可以吗?它有任何性能损失吗?或者写这样的代码会更好:
void DoThis()
{
if (isValid)
{
DoThat();
}
}
回答by Russell
There is no performance penalty, however the second piece of code is more readable and hence easier to maintain.
没有性能损失,但是第二段代码更具可读性,因此更易于维护。
回答by CMS
A return in a void method is not bad, is a common practice to invert if
statements to reduce nesting.
void 方法中的 return 也不错,是反转if
语句以减少嵌套的常见做法。
And having less nesting on your methods improves code readability and maintainability.
减少方法上的嵌套可以提高代码的可读性和可维护性。
Actually if you have a void method without any return statement, the compiler will always generate a ret instructionat the end of it.
实际上如果你有一个没有任何 return 语句的 void 方法,编译器总是会在它的末尾生成一个ret 指令。
回答by Noon Silk
It's perfectly okay and no 'performance penalty', but never ever write an 'if' statement without brackets.
这完全没问题,没有“性能损失”,但永远不要写一个没有括号的“if”语句。
Always
总是
if( foo ){
return;
}
It's way more readable; and you'll never accidentally assume that some parts of the code are within that statement when they're not.
它更具可读性;并且您永远不会意外地假设代码的某些部分不在该语句中。
回答by SO User
Bad practice??? No way. In fact, it is always better to handle validations by returning from the method at the earliest if validations fail. Else it would result in huge amount of nested ifs & elses. Terminating early improves code readability.
不好的做法???没门。事实上,如果验证失败,最好尽早从方法返回来处理验证。否则会导致大量嵌套的 ifs & elses。提前终止可以提高代码的可读性。
Also check the responses on a similar question: Should I use return/continue statement instead of if-else?
还要检查对类似问题的回答:我应该使用 return/continue 语句而不是 if-else 吗?
回答by Imagist
In this case, your second example is better code, but that has nothing to do with returning from a void function, it's simply because the second code is more direct. But returning from a void function is entirely fine.
在这种情况下,您的第二个示例是更好的代码,但这与从 void 函数返回无关,只是因为第二个代码更直接。但是从 void 函数返回完全没问题。
回答by Mike Hall
It's not bad practice (for all reasons already stated). However, the more returns you have in a method, the more likely it should be split into smaller logical methods.
这不是坏习惯(出于已经说明的所有原因)。但是,方法中的返回值越多,就越有可能将其拆分为更小的逻辑方法。
回答by John R. Strohm
I'm going to disagree with all you young whippersnappers on this one.
在这个问题上,我将不同意你们所有年轻的鞭打者。
Using return in the middle of a method, void or otherwise, is very bad practice, for reasons that were articulated quite clearly, nearly forty years ago, by the late Edsger W. Dijkstra, starting in the well-known "GOTO Statement Considered Harmful", and continuing in "Structured Programming", by Dahl, Dijkstra, and Hoare.
在方法中间使用 return,无论是 void 还是其他方法,都是非常糟糕的做法,其原因在将近四十年前已故的 Edsger W. Dijkstra 从著名的“GOTO 语句被认为有害”,并继续阅读 Dahl、Dijkstra 和 Hoare 所著的“结构化编程”。
The basic rule is that every control structure, and every module, should have exactly one entry and one exit. An explicit return in the middle of the module breaks that rule, and makes it much harder to reason about the state of the program, which in turn makes it much harder to say whether the program is correct or not (which is a much stronger property than "whether it appears to work or not").
基本规则是每个控制结构和每个模块都应该只有一个入口和一个出口。模块中间的显式返回打破了该规则,并且使程序状态的推理变得更加困难,这反过来又使判断程序是否正确变得更加困难(这是一个更强大的属性而不是“无论它是否有效”)。
"GOTO Statement Considered Harmful" and "Structured Programming" kicked off the "Structured Programming" revolution of the 1970s. Those two pieces are the reasons we have if-then-else, while-do, and other explicit control constructs today, and why GOTO statements in high-level languages are on the Endangered Species list. (My personal opinion is that they need to be on the Extinct Species list.)
“GOTO 语句被认为有害”和“结构化编程”拉开了 1970 年代“结构化编程”革命的序幕。这两部分是我们今天拥有 if-then-else、while-do 和其他显式控制结构的原因,以及为什么高级语言中的 GOTO 语句在濒危物种列表中的原因。(我个人的意见是它们需要被列入灭绝物种名单。)
It is worth noting that the Message Flow Modulator, the first piece of military software that EVER passed acceptance testing on the first try, with no deviations, waivers, or "yeah, but" verbiage, was written in a language that did not even have a GOTO statement.
值得注意的是,消息流调制器是第一款首次通过验收测试的军用软件,没有任何偏差、弃权或“是的,但是”的措辞,它是用一种甚至没有的语言编写的GOTO 语句。
It is also worth mentioning that Nicklaus Wirth changed the semantics of the RETURN statement in Oberon-07, the latest version of the Oberon programming language, making it a trailing piece of the declaration of a typed procedure (i.e., function), rather than an executable statement in the body of the function. His explication of the change said that he did it precisely because the previous form WASa violation of the one-exit principle of Structured Programming.
还值得一提的是,Nicklaus Wirth 更改了 Oberon-07(Oberon 编程语言的最新版本)中 RETURN 语句的语义,使其成为类型化过程(即函数)声明的尾随部分,而不是函数体中的可执行语句。他的变化解释说,他这样做是正是因为以前的形式WAS违反了结构化编程的一个退出的原则。
回答by cdmckay
The first example is using a guard statement. From Wikipedia:
第一个示例是使用保护语句。来自维基百科:
In computer programming, a guard is a boolean expression that must evaluate to true if the program execution is to continue in the branch in question.
在计算机编程中,守卫是一个布尔表达式,如果程序要在所讨论的分支中继续执行,它的计算结果必须为真。
I think having a bunch of guards at the top of a method is a perfectly understandable way to program. It is basically saying "do not execute this method if any of these are true".
我认为在一个方法的顶部有一堆守卫是一种完全可以理解的编程方式。它基本上是在说“如果其中任何一个为真,则不要执行此方法”。
So in general it would like this:
所以一般来说它会是这样的:
void DoThis()
{
if (guard1) return;
if (guard2) return;
...
if (guardN) return;
DoThat();
}
I think that's a lot more readable then:
我认为那更具可读性:
void DoThis()
{
if (guard1 && guard2 && guard3)
{
DoThat();
}
}
回答by Jason Williams
There is another great reason for using guards (as opposed to nested code): If another programmer adds code to your function, they are working in a safer environment.
使用守卫(而不是嵌套代码)还有另一个重要原因:如果另一个程序员向您的函数添加代码,他们将在更安全的环境中工作。
Consider:
考虑:
void MyFunc(object obj)
{
if (obj != null)
{
obj.DoSomething();
}
}
versus:
相对:
void MyFunc(object obj)
{
if (obj == null)
return;
obj.DoSomething();
}
Now, imagine another programmer adds the line: obj.DoSomethingElse();
现在,假设另一个程序员添加了以下行: obj.DoSomethingElse();
void MyFunc(object obj)
{
if (obj != null)
{
obj.DoSomething();
}
obj.DoSomethingElse();
}
void MyFunc(object obj)
{
if (obj == null)
return;
obj.DoSomething();
obj.DoSomethingElse();
}
Obviously this is a simplistic case, but the programmer has added a crash to the program in the first (nested code) instance. In the second example (early-exit with guards), once you get past the guard, your code is safe from unintentional use of a null reference.
显然这是一个简单的情况,但程序员在第一个(嵌套代码)实例中为程序添加了崩溃。在第二个示例中(使用守卫提前退出),一旦您通过守卫,您的代码就不会意外使用空引用。
Sure, a great programmer doesn't make mistakes like this (often). But prevention is better than cure - we can write the code in a way that eliminates this potential source of errors entirely. Nesting adds complexity, so best practices recommend refactoring code to reduce nesting.
当然,一个伟大的程序员不会(经常)犯这样的错误。但是预防胜于治疗 - 我们可以以完全消除这种潜在错误来源的方式编写代码。嵌套会增加复杂性,因此最佳实践建议重构代码以减少嵌套。
回答by Dhananjay
Throw exception instead of returning nothing when object is null etc.
当对象为空等时抛出异常而不是返回任何内容。
Your method expects object to be not null and is not the case so you should throw exception and let caller handle that.
您的方法期望 object 不为 null 而事实并非如此,因此您应该抛出异常并让调用者处理它。
But early return is not bad practice otherwise.
但是,否则提前返回也不是坏习惯。