ByVal (Visual Basic)
Указывает, что аргумент передается по значению, поэтому вызываемая процедура или свойство не может изменить значение переменной, лежащей в основе аргумента в вызывающем коде. Если модификатор не указан, ByVal используется по умолчанию.
Так как это значение по умолчанию, не нужно явно указывать ByVal ключевое слово в сигнатурах методов. Он, как правило, создает шумный код и часто приводит к нестандартной ByRef ключевое слово пропускается.
Замечания
Модификатор ByVal можно использовать в следующих контекстах:
Пример
В следующем примере показано использование механизма передачи ByVal параметров с аргументом ссылочного типа. В примере аргумент — c1 экземпляр класса Class1 . ByVal Запрещает коду в процедурах изменять базовое значение ссылочного аргумента, c1 но не защищает доступные поля и свойства c1 .
Module Module1 Sub Main() ' Declare an instance of the class and assign a value to its field. Dim c1 As New Class1() c1.Field = 5 Console.WriteLine(c1.Field) ' Output: 5 ' ByVal does not prevent changing the value of a field or property. ChangeFieldValue(c1) Console.WriteLine(c1.Field) ' Output: 500 ' ByVal does prevent changing the value of c1 itself. ChangeClassReference(c1) Console.WriteLine(c1.Field) ' Output: 500 Console.ReadKey() End Sub Public Sub ChangeFieldValue(ByVal cls As Class1) cls.Field = 500 End Sub Public Sub ChangeClassReference(ByVal cls As Class1) cls = New Class1() cls.Field = 1000 End Sub Public Class Class1 Public Field As Integer End Class End Module
См. также
- Удалить ByVal (правило стиля IDE0081)
- Ключевые слова
- Передача аргументов по значению и по ссылке
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Передача аргументов по значению и по ссылке (Visual Basic)
В Visual Basic можно передать аргумент в процедуру по значению или по ссылке. Это называется механизмом передачи и определяет, может ли процедура изменять элемент программирования, базовый аргумент в вызывающем коде. Объявление процедуры определяет механизм передачи для каждого параметра, указав ключевое слово ByVal или ByRef.
Различия
При передаче аргумента в процедуру следует учитывать несколько различных различий, взаимодействующих друг с другом:
- Является ли базовый элемент программирования измененным или неизменяемым
- Является ли сам аргумент модификируемым или неизменяемым
- Указывает, передается ли аргумент по значению или по ссылке
- Тип данных аргумента является типом значений или ссылочным типом
Выбор механизма передачи
Необходимо тщательно выбрать механизм передачи для каждого аргумента.
- Защита. При выборе между двумя механизмами передачи наиболее важным критерием является воздействие вызывающих переменных для изменения. Преимущество передачи аргумента ByRef заключается в том, что процедура может возвращать значение вызывающему коду через этот аргумент. Преимущество передачи аргумента ByVal заключается в том, что он защищает переменную от изменения процедурой.
- Производительность. Хотя механизм передачи может повлиять на производительность кода, разница обычно незначительна. Одним из исключений является переданный ByVal тип значения. В этом случае Visual Basic копирует все содержимое аргумента. Таким образом, для большого типа значений, например структуры, он может быть более эффективным для передачи. ByRef Для ссылочных типов копируется только указатель на данные (четыре байта на 32-разрядных платформах, восемь байтов на 64-разрядных платформах). Таким образом, аргументы типа String или Object значения можно передавать без ущерба для производительности.
Определение механизма передачи
Объявление процедуры указывает механизм передачи для каждого параметра. Вызывающий ByVal код не может переопределить механизм.
Если параметр объявлен с ByRef , вызывающий код может принудительно заставить механизм, ByVal заключив имя аргумента в скобки в вызове. Дополнительные сведения см. в разделе «Практическое руководство. Принудительное передача аргумента по значению».
Значение по умолчанию в Visual Basic — передавать аргументы по значению.
Передача аргумента по значению
- Если вызывающий элемент кода, лежащий в основе аргумента, является неизменяемым элементом, объявите соответствующий параметр ByVal. Код не может изменить значение неизменяемого элемента.
- Если базовый элемент является изменяемым, но не требуется, чтобы процедура могла изменить его значение, объявите параметр ByVal . Только вызывающий код может изменить значение изменяемого элемента, передаваемого по значению.
Передача аргумента по ссылке
- Если процедуре требуется изменить базовый элемент в вызывающем коде, объявите соответствующий параметр ByRef.
- Если правильное выполнение кода зависит от процедуры изменения базового элемента в вызывающем коде, объявите параметр ByRef . Если передать его по значению или если вызывающий код переопределяет ByRef механизм передачи, заключив аргумент в скобки, вызов процедуры может привести к непредвиденным результатам.
Пример
Description
В следующем примере показано, когда передавать аргументы по значению и когда передавать их по ссылке. Процедура 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
См. также
- Процедуры
- Параметры и аргументы процедуры
- Практическое руководство. Передача аргументов в процедуру
- Практическое руководство. Изменение значения аргумента процедуры
- Практическое руководство. Защита аргумента процедуры от изменений значения
- Практическое руководство. Принудительная передача аргумента по значению
- Передача аргументов по позиции и по имени
- Типы значений и ссылочные типы
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Эффективная передача аргументов
Все аргументы передаются в процедурыпо ссылке, если иное не указано явно. Передача аргументов по ссылке позволяет повысить эффективность, поскольку в этом случае для передачи аргумента в процедуру требуется одинаковое количество времени и памяти (4 байта) независимо от его типа данных.
Чтобы передать аргумент по значению, включите в объявление процедуры ключевое слово ByVal. Аргументы, передаваемые значением, потребляют от 2 до 16 байт в процедуре в зависимости от типа данных аргумента. Передача крупных типов данных занимает немного больше времени. В связи с этим не рекомендуется передавать по значению типы данных String и Variant.
При передаче аргумента по значению исходная переменная копируется. Изменения аргумента в рамках процедуры не отражаются на исходной переменной. Например:
Function Factorial (ByVal MyVar As Integer) ' Function declaration. MyVar = MyVar - 1 If MyVar = 0 Then Factorial = 1 Exit Function End If Factorial = Factorial(MyVar) * (MyVar + 1) End Function ' Call Factorial with a variable S. S = 5 Print Factorial(S) ' Displays 120 (the factorial of 5) Print S ' Displays 5.
Если в объявление функции не включено ключевое слово ByVal, предшествующий оператор Print отобразит значения 1 и 0. Это связано с тем, что MyVar затем будет ссылаться на переменную S , которая уменьшается на 1, пока не будет равно 0.
Так как ByVal создает копию аргумента, он позволяет передать вариант функции Factorial . Если процедура, в которой объявляется аргумент, имеет другой тип данных, передать вариант по ссылке нельзя.
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Ссылки на ByVal в Microsoft Forms
Ключевое слово ByVal в Microsoft Forms указывает, что аргумент передается в качестве значения; это стандартное значение ByVal в Visual Basic. Однако в Microsoft Forms можно использовать ByVal с объектом ReturnBoolean, ReturnEffect, ReturnInteger или ReturnString. В этом случае передаваемое значение не относится к простому типу данных, а является указателем на объект.
При использовании с такими объектами ByVal ссылается на объект, а не на параметры метода передачи. Каждый из перечисленных ранее объектов имеет свойство Value , которое можно задать. Вы также можете передавать это значение в функцию и из нее. Поскольку вы можете изменять значения элементов объекта, события приводят к результатам, соответствующим поведению ByRef, хотя в синтаксисе события указано, что используется параметр ByVal.
Назначение значения аргументу, связанному с ReturnBoolean, ReturnEffect, ReturnInteger или ReturnString , ничем не отличается от задания значения любого другого аргумента. Например, если синтаксис события указывает, что аргумент Cancel используется с объектом ReturnBoolean , инструкция по-прежнему действительна, как и для других типов данных.
См. также
- Контексты ключевых слов
- Справочник по Microsoft Forms
- Темы по основам Microsoft Forms
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.