【发布时间】:2015-03-06 08:10:54
【问题描述】:
我有一个函数(表单中的事件处理程序),其结构如下:
Dim errMsg as String = ""
CheckIfValidUser(..., errMsg)
If errMsg.Length > 0 Then
ShowError(errMsg)
LogError(errMsg)
Return
End If
CheckIfBookAvailable(..., errMsg)
If errMsg.Length > 0 Then
ShowError(errMsg)
LogError(errMsg)
Return
End If
ReserveBook(..., errMsg)
If errMsg.Length > 0 Then
ShowError(errMsg)
LogError(errMsg)
Return
End If
BookReserved = True
我注意到大部分代码都是类似的结构,所以我尝试重构如下:
Dim errMsg as String = ""
Dim HandleError = Sub()
If errMsg.Length > 0 Then
ShowError(errMsg)
LogError(errMsg)
Return
End If
End Sub
CheckIfValidUser(..., errMsg)
HandleError()
CheckIfBookAvailable(..., errMsg)
HandleError()
ReserveBook(..., errMsg)
HandleError()
BookReserved = True
但它不起作用,因为我需要“返回两次”而不是仅仅从嵌套函数返回!使用 goto 也不起作用,因为现有标签超出了嵌套函数的范围。
在 .net 中有没有办法做到这一点?我知道可以从 HandleError 返回一个布尔值并在其上分支,但随后它又回到相同的重复结构。
【问题讨论】:
-
这是一种非常古老的编码风格。更现代的风格是让每个执行验证的函数在出现问题时抛出 exception,然后(通常尽可能高)有一个捕获这些异常的异常处理程序,显示消息并记录它们。
-
@Damien_The_Unbeliever 哦,我没注意到这是一种旧风格;我只是发现以这种方式编写时流程很明显。抛出异常对我来说有点模棱两可:您无法通过仅查看调用来判断哪个函数将/不会抛出异常(以及哪些异常)!
-
以同样的方式,您无法仅通过查看此代码来判断哪些情况会导致
errMsg在任何这些方法中具有非零长度。一般来说,好的文档对于治愈这些弊病有很长的路要走。而且,至少在例外情况下,您不能忘记检查errMsg。