8

最近我一直在处理遗留的 vb.net 代码,在代码同行评审期间,建议不要使用 Exit Sub / Function,而是将所有功能嵌套在 IF 语句中。

当我最初开始开发时,我本能地这样做(嵌套 IF),不仅看起来更合乎逻辑,而且看起来不那么令人困惑。

然而,在某些时候,我与一个将嵌套 IF 视为“邪恶”的团队合作,因此我被告知的 Exit subs / functions 是首选。我很确定他们制作了一些 MS 最佳实践材料来支持这一点。

所以这个问题是针对有经验的开发人员的,哪种方式才是真正的首选?如果您给出答案,您还可以说明您的来源,或者只是提及这是您的团队/公司/个人的偏好并给出原因。

提前致谢。

按要求编辑:代码示例

退出子:

Private Sub DoSomeWork()
 if not conditionMetFromAnotherFunction() then
      exit Sub 
 end if

 'Method work starts here
End Sub

嵌套 IF:

Private Sub DoSomeWork()
 if conditionMetFromAnotherFunction() then
     'Method work starts here
 end if
End Sub
4

6 回答 6

22

If you don't exit your functions early, you will reach a point where your code looks like this:

stumble on code

No one can tell me this is a better style than returning early from a function.

于 2012-07-09T12:16:58.420 回答
6

在代码同行评审期间,建议不要使用 Exit Sub / Function,而是将所有功能嵌套在 IF 语句中。

这是一个可怕的建议。就这么简单。忽略它。事实上,通常情况正好相反,特别是在需要嵌套缩进的情况下,或者您检查参数的有效性并可能提前退出的情况下:您问题中的代码就是一个很好的例子。在此处使用提前退出。

没有“官方”来源(什么是官方的?),但优秀的程序员之间几乎达成共识,只有极少数人反对。有关这方面的更多讨论,请参阅关于 Programmers 的讨论

但是,我建议使用Return而不是Exit {Sub|Function}.

于 2012-07-09T12:13:32.070 回答
4

As David pointed out in his comment, nested if statements can add to the complexity of your code.

Imagine the following (simplified) code :

Private Sub DoSomeWork()
    if conditionMetFromAnotherFunction() then
        if conditionDependantUponPreviousCondition then
            ' Do the work
        end if
    end if
End Sub

Or the following

Private Sub DoSomeWork()
    if not conditionMetFromAnotherFunction()
        return
    else if not conditionDependantUponPreviousCondition 
        return
    end if


    ' If we're here, everything's all good
    ' Do the work...
End Sub

If your conditions get more complex, returning makes it much more easy to understand that under some conditions, your code is not doing anything, and makes your code more readable.

Otherwise, you have to read all the function and mentally parse the nested if's to see that nothing's done.

于 2012-07-09T12:17:48.513 回答
3

As with anything, "it depends." Either one can be distasteful if used in the wrong context.

For example, what is conditionMetFromAnotherFunction() checking? If it's checking some kind of required pre-condition for DoSomeWork() then I'd even go so far as to through an exception instead of just quietly exiting the function. ArgumentException would be useful if it was checking the validity of an argument passed to the function, for example. Quietly exiting doesn't seem right if something in the system was actually wrong.

For the nested conditionals, that's definitely messy. Keep in mind the rule of thumb that a function should "do one thing." Checking that condition is one thing. So in that case the 'Method work starts here should be nothing more than a call to another method which actually does the work. It should not be many lines of code all wrapped in one big conditional. And the function names should accurately reflect what it is they're doing. So this one would be DoWorkIfConditional (in the contrived example) and the other method would be DoWork.

It's OK for the functions to check pre-conditions before doing work. If pre-conditions aren't met, I'd consider throwing an exception. But that depends on the actual logic of the application which isn't really conveyed in this example.

于 2012-07-09T12:17:21.000 回答
2

I suggest reading the answers here for a good roundup on this topic.

To summarize: Single Entry / Single Exit developed in languages where you can have multiple entry points to a function and you can also return to different positions in the code. It has been misinterpreted as allowing only one point in the code where you can return from.

The "best practice" to use only one return / exit statement in a subprogram comes from languages with explicit heap management, where the resources of a subprogram are freed at the end of the subprogram, so the control flow is required to pass through there. This is not applicable in languages that are based on .NET or JVM.

Overall, code is usually more readable when you are allowed to use multiple returns.

于 2012-07-09T12:16:31.777 回答
1

IMO nested if's are a very quick rout to horrid spaghetti code. Generally speaking if your deeply nesting you code then your trying to do to much work in your method and most likely will benefit from refactoring into smaller parts.

Having said that sometimes it cannot be avoided so there is no one answer fits all.

于 2012-07-09T12:18:27.310 回答