我有一些代码(另一个开发人员写的)我需要修改,因为ExecuteProc过程失败.(它失败的原因不在于这个问题的范围.这是一个很长的故事),但范围是我不确定为什么NullReferenceException会发生.它是在VB.NET中(我自己不是VB.NET的人,所以我不确定这是否是VB.NET特有的):
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports System.Collections
'(...)
Public Overloads Function ExecuteProc( ByVal pvsProcName as String) As DataSet
Dim oCommand As SqlCommand
Dim oDataAdaptor As SqlDataAdapter = New SqlDataAdapter
'Other Stuff here
Try
oCommand = CommandGet(ConnectionGet)
'Do some more stuff that's irrelevant
Catch oException As Exception
Throw oException
Finally
ConnectionClose(oCommand.Connection)
oCommand.Dispose()
oDataAdaptor.Dispose()
End Try
End Function
Run Code Online (Sandbox Code Playgroud)
我收到以下警告:
Variable 'oCommand' is used before it has been assigned a value. A null reference exception could result at runtime.`
Run Code Online (Sandbox Code Playgroud)
编辑:我在发布问题之前就找到了答案.我发布它以保持它周围(我讨厌把十分钟的东西扔进去,不知不觉).
我对VB.NET人员的后续问题是这样的:
以下两个初始化会有什么不同:
Dim oCommand As SqlCommand = Nothing
Run Code Online (Sandbox Code Playgroud)
和:
Dim oCommand as New SqlComand
Run Code Online (Sandbox Code Playgroud)
好吧,最明显的是,如果CommandGet失败并抛出一个异常,oCommand将不会被设置 - 它仍然是null,所以oCommand.Connection在Finally块中会抛出一个NullReferenceException.
另外,我会说:
Catch块Using块(一个用于命令,一个用于适配器)将比明确Try/ Finally块更好IMO编辑:两个解决方案之间的区别很简单 - 一个创建一个"虚拟"命令,然后您可以忽略或处置(但不是两者).另一个显式设置了一个空引用,您可以检查它.
我会使用第三种解决方案 - 使用块:
Using oCommand As CommandGet(ConnectionGet)
' All the normal stuff in here '
End Using
Run Code Online (Sandbox Code Playgroud)