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

StackOverflow https://stackoverflow.com/questions/2357697

  •  23-09-2019
  •  | 
  •  

Вопрос

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

У меня есть много предупреждений, поднятых из-за:

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

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

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

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

Некоторые из других вещей, которые в настоящее время передаются по ссылке ref в моем проекте, являются объектами подключения к базе данных, т. е.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
Это было полезно?

Решение

При определении метода в 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top