Модификатор ByVal обозначает передачу параметра в процедуру или функцию по значению. В Visual Basic ByVal применяется по умолчанию и гарантирует, что изменения, произведенные с параметром внутри процедуры, не затрагивают исходную переменную, переданную вызывающей стороной.
В классических версиях VB любой параметр можно было передать двумя способами: по значению или по ссылке. С развитием языка и появлением сложных типов данных (структуры, классы) выросла важность осознанного выбора между ByVal и ByRef.
Ошибочный выбор способа передачи параметра часто приводит к ошибкам: можно непреднамеренно изменить переменную вызывающего кода, либо наоборот — ждать изменений, которые не произойдут.
ByVal используют, когда процедуре нужно работать с копией значения. Применяется для передачи примитивных типов, структур, иногда даже ссылочных типов, если важно сохранить ссылку.
Пример кода:
Sub Increment(ByVal number As Integer) number += 1 End Sub Dim myValue As Integer = 10 Increment(myValue) Console.WriteLine(myValue) ' Вернет 10, не 11
Ключевые особенности:
Как поведет себя объект (например, экземпляр класса), если его передать с модификатором ByVal?
Ответ: Передается копия ссылки на объект, а не сам объект. Можно изменить поля объекта из процедуры — изменения будут видны снаружи. Именно ссылку, а не объект, нельзя заменить на новую внутри процедуры с эффектом для вызвавшего кода.
Пример кода:
Class Counters Public Value As Integer End Class Sub ModifyCounter(ByVal c As Counters) c.Value = 999 ' Меняет свойство! c = New Counters() ' Это изменение не видно вызывающему коду End Sub Dim example As New Counters() ModifyCounter(example) Console.WriteLine(example.Value) ' Выведет 999
Изменится ли значение структуры при передаче ByVal, если ее поля менять внутри процедуры?
Ответ: Нет, весь экземпляр структуры копируется, и изменения не попадают наружу. Каждая запись структуры, например, Point, в процедуре своя.
Обязательно ли явно указывать ByVal для параметра?
Ответ: Нет, ByVal используется по умолчанию, явное указание только для большей читаемости и соблюдения стиля кодирования.
Разработчик передает массив ByVal в функцию, ожидая что элементы можно будет внести в массив и появится новый массив у вызывающей стороны (де-факто Reference Type передается по ссылке).
Плюсы:
Минусы:
Для передачи индекса массива, который не должен изменяться функцией, используется ByVal. Даже если внутри меняют значение индекса, исходная переменная не затронута.
Плюсы:
Минусы: