Передача аргументов по значению и по ссылке (Visual Basic)
В Visual Basic можно передать аргумент в процедуру по значению или по ссылке.Это называется механизмом передачи. Он определяет, может ли процедура изменять элемент программирования, содержащийся в аргументе кода вызова.Объявление процедуры определяет механизм передачи для каждого параметра путем указания ключевого слова ByVal (Visual Basic) или ByRef (Visual Basic).
Различия
При передаче аргумента в процедуру, нужно принять во внимание несколько отличительных особенностей, которые взаимодействуют друг с другом.
Является ли базовый элемент программирования изменяемым или неизменяемым
Является ли сам аргумент изменяемым или неизменяемым
Аргумент передается по значению или по ссылке
Является ли тип данных аргумента типом значения или ссылочным типом
Дополнительные сведения см. в разделах Различия между аргументами Modifiable и Nonmodifiable (Visual Basic) и Различия между передачей аргумента по значению и по ссылке (Visual Basic).
Выбор механизма передачи
Необходимо осторожно выбирать механизм передачи для каждого аргумента.
Защита.Наиболее важным критерием выбора между двумя механизмами передачи является требуемая степень доступности исходных переменных для изменения.Преимущество передачи аргумента ByRef заключается в том, что процедура может возвратить значение в вызывающий код через этот аргумент.Преимущество передачи аргумента ByVal состоит в том, что в этом случае переменная защищена от изменений, вносимых процедурой.
Производительность.Хотя механизм передачи также может повлиять на производительность кода, разница практически не заметна.Единственным исключением является передача типа значения ByVal.В этом случае Visual Basic копирует все содержимое аргумента.Таким образом, большие аргументы типа значения (например структуру) целесообразнее передавать ByRef.
Для ссылочных типов копируется только указатель на данные (четыре байта на 32-разрядных платформах, восемь байтов на 64-разрядных платформах).Таким образом можно передавать аргументы типа String или Object по значению без потери производительности.
Определение механизма передачи
Объявление процедуры определяет механизм передачи для каждого параметра.Вызывающий код не может переопределить механизм ByVal.
Если параметр объявлен с ByRef, то вызывающий код может применять механизм для ByVal, заключив имя аргумента в круглые скобки в вызове.Дополнительные сведения см. в разделе Практическое руководство. Принудительная передача аргумента по значению (Visual Basic).
По умолчанию в Visual Basic для передачи аргументов используется передача по значению.
Когда передавать аргумент по значению
Если элемент кода вызова, содержащийся в аргументе, является неизменяемым, объявите соответствующий параметр ByVal (Visual Basic).Никакой код не может изменить значение неизменяемого элемента.
Если элемент является изменяемым, но процедура не должна изменить его значение, объявите параметр ByVal.Только вызывающий код может изменить значение изменяемого элемента, который передается по значению.
Когда передавать аргумент по ссылке
Если процедуре необходимо изменить базовый элемент в коде вызова, объявите соответствующий параметр ByRef (Visual Basic).
Если правильное выполнение кода зависит от изменения базового элемента в коде вызывающей процедуры, объявите параметр ByRef.Если параметр передается его по значению или код вызова переопределяет ByRef механизма передачи, заключив аргумент в круглые скобки, вызов процедуры может привести к непредсказуемым результатам.
Пример
Описание
Следующий пример показывает, когда следует передавать аргументы по значению, а когда передавать их по ссылке.Процедура Calculate имеет два параметра: ByVal и ByRef.Если дана процентная ставка rate и сумма средств debt, задачей процедуры является вычисление нового значения debt, которое будет результатом применения процентной ставки к исходному значению debt.Поскольку debt является параметром ByRef, новая сумма отражается в значении аргумента в вызывающем коде, соответствующем debt.Параметр rate является параметром ByVal, так как процедура Calculate не должна менять его значение.
Код
Module Module1
Sub Main()
' Two interest rates are declared, one a constant and one a
' variable.
Const highRate As Double = 12.5
Dim lowRate = highRate * 0.6
Dim initialDebt = 4999.99
' Make a copy of the original value of the debt.
Dim debtWithInterest = initialDebt
' Calculate the total debt with the high interest rate applied.
' Argument highRate is a constant, which is appropriate for a
' ByVal parameter. Argument debtWithInterest must be a variable
' because the procedure will change its value to the calculated
' total with interest applied.
Calculate(highRate, debtWithInterest)
' Format the result to represent currency, and display it.
Dim debtString = Format(debtWithInterest, "C")
Console.WriteLine("What I owe with high interest: " & debtString)
' Repeat the process with lowRate. Argument lowRate is not a
' constant, but the ByVal parameter protects it from accidental
' or intentional change by the procedure.
' Set debtWithInterest back to the original value.
debtWithInterest = initialDebt
Calculate(lowRate, debtWithInterest)
debtString = Format(debtWithInterest, "C")
Console.WriteLine("What I owe with low interest: " & debtString)
End Sub
' Parameter rate is a ByVal parameter because the procedure should
' not change the value of the corresponding argument in the
' calling code.
' The calculated value of the debt parameter, however, should be
' reflected in the value of the corresponding argument in the
' calling code. Therefore, it must be declared ByRef.
Sub Calculate(ByVal rate As Double, ByRef debt As Double)
debt = debt + (debt * rate / 100)
End Sub
End Module
См. также
Задачи
Практическое руководство. Передача аргументов в процедуру (Visual Basic)
Практическое руководство. Изменение значения аргумента процедуры (Visual Basic)
Практическое руководство. Защита аргумента процедуры от изменения значения (Visual Basic)
Практическое руководство. Принудительная передача аргумента по значению (Visual Basic)
Основные понятия
Параметры и аргументы процедуры (Visual Basic)