【问题标题】:Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time变量“reader”在被赋值之前被使用。运行时可能会导致空引用异常
【发布时间】:2018-02-03 04:58:12
【问题描述】:

尝试修复警告,但不确定如何将代码重组为 reader.IsClosed 会引发警告,指出“变量‘reader’在被赋值之前已被使用。运行时可能会导致空引用异常。 "从逻辑上讲,由于 reader As SqlDataReader && reader 没有使用值初始化,所以我可以忽略 as 在运行时应该没问题,但我的经验不足会让我相信有更好的方法吗?

Public Function GetTotalItems(ByVal userId As Long) As Int16

    Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
    Dim tablMd = Me.GetMetaData()
    Dim retList As ArrayList = New ArrayList()

    lstParam.Add(New SqlClient.SqlParameter("@" + tablMd.PrimaryKey.ColumnName, 0))
    lstParam.Add(New SqlClient.SqlParameter("@UserID", userId))
    lstParam.Add(New SqlClient.SqlParameter("@ActionFlag", "SELECT_ITEMS_COUNT"))

    Dim spName As String = Me.GetStoreProcname()
    Dim reader As SqlDataReader
    Try
        reader = SqlHelper.ExecuteReader(
            Utility.GetConnectionStringSetting(),
            CommandType.StoredProcedure,
            Me.GetStoreProcname(),
            lstParam.ToArray()
        )

        If (reader.HasRows = True) Then
            If (reader.Read()) Then
                Dim value As Object = reader(0)

                Return CInt(value)

            End If

        End If

    Catch ex As Exception
        Throw

    Finally
        If Not reader.IsClosed Then
            reader.Close()
        End If
    End Try

    Return 0

End Function

【问题讨论】:

  • 提示:Dim reader As SqlDataReader需要修改,为你DIY。另外你最好开始使用using
  • 更具体地说,当您在 Finally 块中获取其 IsClosed 属性时,您假设 reader 具有值,但如果您的 SqlHelper.ExecuteReader 方法抛出异常,则 @987654329 @ 在那时将没有值。
  • 另外,您的Catch 块完全没有意义。如果您有 Finally 块,则不需要 Catch 块,因此如果您不打算在其中做任何事情,请不要添加一个块。尽管如此,您应该使用Using 块。如果你这样做,那么你可以取消整个Try...Catch...Finally,因为它会实现同样的事情,而没有NullReferenceException的可能性。
  • 添加到@jmcilhinney 简要解释的内容,保留Options Strict & Explicit ON
  • 如果您在 Using 块中创建阅读器,则无需在 finally 块中关闭它,而且您将消除警告。

标签: vb.net


【解决方案1】:

我们可以将问题缩小到以下摘录:

Dim reader As SqlDataReader
Try
    reader = SqlHelper.ExecuteReader( ... )
Finally
    If Not reader.IsClosed Then reader.Close()
End Try

如果ExecuteReader() 函数抛出异常,就会出现问题。在这种情况下,reader 变量永远不会被赋值。当您尝试评估reader.IsClosed 时,它仍然是Nothing,并且 将导致异常。

鉴于您实际上并没有对异常执行任何操作,并且 SqlHelper 负责连接和命令对象,您可以将整个函数缩小到仅此:

Public Function GetTotalItems(ByVal userId As Long) As Int16
    Dim lstParam = {
       New SqlClient.SqlParameter("@" + Me.GetMetaData().PrimaryKey.ColumnName, 0),
       New SqlClient.SqlParameter("@UserID", userId),
       New SqlClient.SqlParameter("@ActionFlag", "SELECT_ITEMS_COUNT")
    }

    Using reader As SqlDataReader = SqlHelper.ExecuteReader(
            Utility.GetConnectionStringSetting(),
            CommandType.StoredProcedure,
            Me.GetStoreProcname(),
            lstParam)

        If reader.Read() Then Return CInt(reader(0))
    End Using

    Return 0  
End Function

【讨论】:

  • 所以 (reader.HasRows = True) 是隐式的,并且在读取之前会进行检查,因此不需要嵌套的 If 语句? ...非常感谢您的帮助。
【解决方案2】:

@jmcilhinney、@o_O、@Chris Dunaway ...感谢您的帮助 + 赞赏 + 钦佩您的知识 + 崇敬 == deverence(); ... 这消除了错误:

公共函数 GetTotalAmount(ByVal userId As Long) As Decimal

    Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
    Dim tablMd = Me.GetMetaData()
    Dim retList As ArrayList = New ArrayList()

    lstParam.Add(New SqlClient.SqlParameter("@" + tablMd.PrimaryKey.ColumnName, 0))
    lstParam.Add(New SqlClient.SqlParameter("@UserID", userId))
    lstParam.Add(New SqlClient.SqlParameter("@ActionFlag", "SELECT_TOTAL_AMOUNT"))

    Dim spName As String = Me.GetStoreProcname()


    Using reader As SqlDataReader = SqlHelper.ExecuteReader(
            Utility.GetConnectionStringSetting(),
            CommandType.StoredProcedure,
            Me.GetStoreProcname(),
            lstParam.ToArray()
        )

        If (reader.HasRows = True) Then
                If (reader.Read()) Then
                    Dim value As Object = reader(0)

                    Return CDec(value)
                End If
            End If
    End Using

    Return 0

End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多