我有以下 Visual Basic.Net 16.x 程式
Module Program
Sub Main(args As String())
Dim sFileName As String = "VBnet_TextFileIO.txt"
Dim sTextToWrite As String = "Hello From VB.net" vbCrLf "Second Line "
Dim myFileStreamWriter As StreamWriter = Nothing
Try
myFileStreamWriter = New StreamWriter(sFileName, 'Pass the file path and name to the StreamWriter constructor.
True) 'Indicate that Append is True, so file will not be overwritten.
myFileStreamWriter.WriteLine(sTextToWrite)
myFileStreamWriter.Close() 'control do not reach here when exception occurs
Catch ex As Exception
Console.WriteLine("An Exception Occurred")
Finally
myFileStreamWriter.Close() 'Compiler says System.NullReferenceException:
'Object reference not set to an instance of an
object.'
End Try
End Sub
End Module
在最后條款下
編譯器抱怨“ System.NullReferenceException:'物件參考未設定為物件的實體。' myFileStreamWriter 什么都沒有。 ”
為什么編譯器會這樣抱怨?
我假設myFileStreamWriter超出了 finally 子句部分的范圍。我應該如何糾正這個問題?
我應該如何正確關閉 myFileStreamWriter 物件
嘗試部分下發生的例外是 System.UnauthorizedAccessException 通過使檔案由我只讀來創建錯誤條件而創建的。
uj5u.com熱心網友回復:
不,編譯器根本不會告訴你。編譯器可能會向您發出有關潛在空參考的警告,但您報告的是運行時例外。
這里的問題是,唯一可以在該塊中引發例外的行Try是第一行,在這種情況下,將不會StreamWriter創建任何物件,在這種情況下,該變數將是Nothing. 您無法關閉從未創建的物件。
由于多種原因,代碼結構不佳。一方面,您同時呼叫Close了Try塊和Finally塊。塊的全部意義Finally在于執行所需的清理,無論是否引發例外。在您的情況下,如果沒有引發例外,您將關閉該物件兩次。如果拋出例外,將沒有要關閉的物件,因此您應該Close只在Try塊中呼叫并取消該Finally塊。
Using如果您要使用保證處置的陳述句創建物件,那會更好:
Try
Using myFileStreamWriter = New StreamWriter(sFileName, 'Pass the file path and name to the StreamWriter constructor.
True) 'Indicate that Append is True, so file will not be overwritten.
myFileStreamWriter.WriteLine(sTextToWrite)
End Using
Catch ex As Exception
Console.WriteLine("An Exception Occurred")
End Try
如果您根本不創建StreamWriter自己會更好:
Try
File.AppendAllText(sFileName, sTextToWrite)
Catch ex As Exception
Console.WriteLine("An Exception Occurred")
End Try
最后,你幾乎不應該捕捉到Exception型別。只捕獲您合理地認為可以拋出的例外,在這種情況下您將確切地知道它們將是什么特定型別。您還應該在某處記錄例外。然后,您應該處理UnhandledException應用程式的事件以捕獲和記錄任何未預料到的例外,并優雅地關閉而不是崩潰。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489226.html
