3

在方法调用上将 Byref 切换为 Byval

由于以下原因,我提出了许多警告:

“在将 'ByRef' 参数 zzzz 的值复制回匹配的参数时,从 xxxx 到 yyyy 的隐式转换。”

我的感觉是,将函数参数从 byref 更改为 byval 是安全的,因为这些方法中的引用类型指针没有做任何特别的事情,引用类型只是被使用,我认为如果运行,行为将完全相同使用副本而不是原始指针。

另一个考虑是我有两个从基类继承的类。同样的情况发生在 byref 参数导致从基类到更窄的具体类的隐式转换。同样,我也看不出这段代码运行 byval 有任何问题。

在处理引用类型时,有没有人有关于在函数中使用参数的任何提示?

目前在我的项目中通过byref 传递的其他一些东西是数据库连接对象,即OracleConnection 和SqlConnection。是否有充分的理由将这些传递到 byref?

示例 1

在将 'ByRef' 参数 'value' 的值复制回匹配的参数时,从 'Object' 到 'Integer' 的隐式转换。

调用代码:

cmd = New SqlCommand()

cmd.Parameters.Add(CreateParameter("Alpha", SqlDbType.Int,ParameterDirection.Input, -1, AlphaValue))

功能:

Private Function CreateParameter(ByVal parameterName As String, ByVal dbType As SqlDbType, ByVal direction As ParameterDirection, ByVal size As Integer, ByRef value As Object) As SqlParameter
    Dim retParam As SqlParameter
    retParam = New SqlParameter(parameterName, dbType)
    retParam.Direction = direction
    retParam.Size = size
    retParam.Value = value
    Return retParam
End Function

示例 2

在将“ByRef”参数“reader”的值复制回匹配的参数时,从“System.Data.IDataReader”隐式转换为“System.Data.SqlClient.SqlDataReader”。

调用代码:

Dim reader As new SqlDataReader

ReleaseReader(reader)

方法:

    Public Sub ReleaseReader(ByRef reader As IDataReader)
        If reader IsNot Nothing Then
            If Not reader.IsClosed Then
                reader.Close()
            End If
            reader.Dispose()
        End If
    End Sub
4

1 回答 1

5

在 VB.Net 或 C# 中定义方法时,您应该按值 (ByVal) 传递参数,除非您需要利用 ByRef 语义。如果您没有在方法中重置参数值,那么您绝对应该将它们转换为 ByVal 调用。

如果您正在重置引用但没有从调用站点利用它,那么我将编写一个辅助方法,该方法采用参数 ByVal 并调用采用 ByRef 的方法。这将删除警告,因为生成的代码不会受到缩小转换错误的影响。

例如:

Public Sub ExampleMethod(ByRef p1 As Object) 
  p1 = "foo"
End Sub

Public Sub ExampleMethodWrapper(ByVal p1 as Object)
  ExampleMethod(p1)
End Sub 

Public Sub Test()
  Dim v1 As String = "hello"
  Dim v2 As String = "world" 
  ExampleMethod(v1) ' Warning generated
  ExampleMethodWrapper(v2) ' No warning
End Sub
于 2010-03-01T17:31:58.613 回答