Переключение Byref в Byval при вызовах методов VB.NET - PullRequest
3 голосов
/ 01 марта 2010

Переключение Byref в Byval при вызовах методов

У меня много предупреждений из-за:

"Неявное преобразование из xxxx в yyyy при копировании значения параметра« ByRef »zzzz обратно в соответствующий аргумент."

Мне кажется, что было бы безопасно изменить параметры функции с byref на byval, так как с указателями ссылочного типа внутри этих методов ничего особенного не делается, ссылочные типы просто используются, и я думаю, что поведение будет точно То же самое, если использовать копию с указателем, а не с оригиналом.

Другое соображение состоит в том, что у меня есть два класса, которые наследуются от базового класса. Та же самая ситуация происходит в том, что параметры byref вызывают неявное приведение от базового класса к более узкому конкретному классу. Опять же, я не вижу никаких проблем с этим кодом, выполняющим byval.

У кого-нибудь есть советы по использованию параметров в функциях при работе со ссылочными типами?

Некоторые другие вещи, которые в настоящее время передаются byref в моем проекте, это объекты подключения к базе данных, то есть OracleConnection и SqlConnection. Есть ли веская причина для их передачи?

Пример 1

Неявное преобразование из 'Object' в 'Integer' при копировании значения параметра 'ByRef' 'value' обратно в соответствующий аргумент.

Телефонный код:

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

Неявное преобразование из «System.Data.IDataReader» в «System.Data.SqlClient.SqlDataReader» при копировании значения параметра «ByRef» «reader» обратно в соответствующий аргумент.

Телефонный код:

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

1 Ответ

5 голосов
/ 01 марта 2010

При определении метода в 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
...