最近我一直致力于传统的vb.net代码,在代码同行评审期间,建议不要使用Exit Sub / Function,而是将所有功能嵌套在IF语句中。
当我最初开始开发时,我习惯性地这样做(嵌入IF),不仅看起来更合乎逻辑,它似乎不那么令人困惑。
然而,在某些时候,我曾与一个将嵌套的IF视为“邪恶”的团队合作,因此我被告知退出子/函数是首选。我很确定他们制作了一些MS最佳实践材料来支持这一点。
所以这个问题适合经验丰富的开发人员,哪种方式真的首选?如果你给出答案,你也可以请说明你的消息来源,或者只是提到这是你的团队/公司/个人首选的偏好并给出理由。
提前致谢。
按要求编辑:代码示例
退出Sub:
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
答案 0 :(得分:22)
如果您没有提前退出功能,您将达到代码如下所示的位置:
没有人能告诉我这是一种比从功能早期返回更好的风格。
答案 1 :(得分:6)
在代码同行评审期间,建议不要使用Exit Sub / Function,而是将所有功能嵌套在IF语句中。
这是一个可怕的建议。就这么简单。忽略它。事实上,相反的情况通常是正确的,特别是在需要嵌套缩进的情况下,或者您检查参数的有效性并可能提前退出的情况:您问题中的代码就是一个很好的例子。 在这里使用提前退出。
没有“官方”来源(官方会是什么?)但是在优秀程序员中几乎达成共识,只有极少数人反对这一点。有关此内容的更多讨论,请参阅discussion on Programmers。
但是,我建议使用Return
代替Exit {Sub|Function}
。
答案 2 :(得分:4)
正如David在他的评论中指出的那样,嵌套if语句会增加代码的复杂性。
想象一下以下(简化)代码:
Private Sub DoSomeWork()
if conditionMetFromAnotherFunction() then
if conditionDependantUponPreviousCondition then
' Do the work
end if
end if
End Sub
或以下
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,以确保没有做任何事情。
答案 3 :(得分:3)
与任何事情一样,"它取决于。"如果在错误的环境中使用,任何一方都会感到厌恶。
例如,什么是conditionMetFromAnotherFunction()
检查?如果它正在检查DoSomeWork()
所需的某种先决条件,那么我甚至可以通过异常而不是只是安静地退出该函数。例如,ArgumentException
在检查传递给函数的参数的有效性时会很有用。如果系统中的某些东西确实是错误的,那么静静地退出似乎并不正确。
对于嵌套条件,肯定凌乱。请记住一个函数应该做一件事的经验法则。" 检查这个条件是一回事。因此,在这种情况下,'Method work starts here
应该只是对另一个实际完成工作的方法的调用。它应该不包含在一个大条件中的许多代码行。 和函数名称应该准确反映它们正在做什么。所以这个是DoWorkIfConditional
(在人为的例子中),另一个方法是DoWork
。
在工作之前检查前置条件的功能是可以的。如果没有满足前提条件,我会考虑抛出异常。但这取决于应用程序的实际逻辑,在这个例子中并没有真正传达。
答案 4 :(得分:2)
我建议您阅读答案here,以便对此主题进行详尽的综述。
总结:单一录入/单退出以您可以拥有多个功能入口点的语言开发,您还可以在代码中返回到不同的位置。它被误解为只允许代码中的一个点,您可以从返回。
在子程序中仅使用一个返回/退出语句的“最佳实践”来自具有显式堆管理的语言,其中子程序的资源在子程序结束时被释放,因此控制流需要通过通过那里。这不适用于基于.NET或JVM的语言。
总的来说,当您被允许使用多个返回时,代码通常更具可读性。
答案 5 :(得分:1)
IMO嵌套,如果是一个非常快速的溃败意大利面条代码。一般来说,如果您深度嵌套您的代码,那么您尝试在您的方法中做很多工作,并且很可能将从重构到较小的部分中受益。
话虽如此,有时候无法避免,所以没有一个答案适合所有人。