我正在vb.net
升级一个大型程序。我正在编写错误处理程序,以便程序可以继续运行,即使存在异常(文件不存在等)。但我对所有错误处理感到困惑。
如果我有多个相互调用的方法,并且我在顶级方法周围添加try catch
,那么在处理异常之后程序将继续运行的位置在哪里?
例如:
public Sub Main()
Dim a As Integer
Try
If (Foo()) Then
a = Boo()
End If
Catch
End Try
'Is a 10 here???
End Sub
public Function Foo() As Boolean
Line1
Line2
Line3
return True
End Function
Public Function Boo() As Int
Line4
Line5
Line6
return 10
End Function
在这种情况下,Boo()
会被调用,例如a
总是= 10
吗? - 即使lines 1-6
上出现例外情况?
答案 0 :(得分:1)
不,在您的示例中,如果Foo
抛出异常,则会立即输入Catch
块。 Boo
函数将不被调用,而a
的值将不被设置。
即使您Main
函数没有使用任何Try / Catch块,也是如此:
Public Sub Main()
Dim a As Integer
If (Foo()) Then
a = Boo()
End If
End Sub
Boo()
只会被调用,a
只会设置为结果,如果Foo
没有抛出异常。如果Foo
抛出,运行时将搜索合适的异常处理程序。找不到一个,这是顶级方法,你将有一个未处理的异常,然后导致应用程序被终止。
这就是为什么不应该将异常用于流量控制,仅用于实际的异常条件。
将仅的内容放在Try
块中,仅包含Catch
个块,用于您知道如何处理的异常处理。我还建议尽可能在声明中初始化变量。一些伪造的代码作为逻辑上如何工作的一个例子:
Public Sub Main()
Dim val As Integer = 0 ' 0 is our "default" value
' Don't need a Try here, this won't throw an exception.
' It will just return an empty string if they canceled.
Dim fileName As String = AskUserForFileName()
' See if they canceled...
If (fileName <> String.Empty)
Try
' Now we need a Try block, because we're going to do
' stuff that might throw an exception.
Dim file As File = OpenFile(fileName)
' Execution won't get here if OpenFile() threw an exception, so
' at this point, we know that the file was opened successfully,
' so we'll try to read our value from it.
val = ReadDataFromFile(file)
' Again, execution won't get here if ReadDataFromFile() threw
' an exception, so we know that the data was read out successfully
' and our val variable has been updated.
Catch ex As FileNotFoundException
MessageBox.Show("Could not find the specified file.")
Catch ex As System.IO.IOException
MessageBox.Show("Could not read from the specified file--check it is valid.")
End Try
End If
' Our variable val will now contain the value read from the file,
' if that whole business was successful. Otherwise, it will
' contain the default value of 0 that we set at the top.
End Sub
在实际代码中,如果抛出异常,您还会广泛使用Using
blocks来处理实现IDisposable
接口的任何对象的自动清理。修改上面的示例,假设我组成的File
类实现了IDisposable
:
Public Sub Main()
Dim val As Integer = 0 ' 0 is our "default" value
' Don't need a Try here, this won't throw an exception.
' It will just return an empty string if they canceled.
Dim fileName As String = AskUserForFileName()
' See if they canceled...
If (fileName <> String.Empty)
Try
' Now we need a Try block, because we're going to do
' stuff that might throw an exception.
Using file As File = OpenFile(fileName)
' Execution won't get here if OpenFile() threw an exception, so
' at this point, we know that the file was opened successfully,
' so we'll try to read our value from it.
val = ReadDataFromFile(file)
' Again, execution won't get here if ReadDataFromFile() threw
' an exception, so we know that the data was read out successfully
' and our val variable has been updated.
End Using ' make sure file always gets closed properly
Catch ex As FileNotFoundException
MessageBox.Show("Could not find the specified file.")
Catch ex As System.IO.IOException
MessageBox.Show("Could not read from the specified file--check it is valid.")
End Try
End If
' Our variable val will now contain the value read from the file,
' if that whole business was successful. Otherwise, it will
' contain the default value of 0 that we set at the top.
End Sub