Передача ссылочных параметров по значению
В 11.4.1 я без объяснений упомянул, что при передаче параметров процедур слово ByVal теряет свою способность к защите по отношению к строкам, массивам и объектам. Теперь мы можем понять, почему это происходит. Рассмотрим такой код:
Public Class Form1
Inherits System.Windows.Forms.Form
Windows Form Designer generated code
Class Класс
Public Поле As Integer
End Class
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim A As New Класс
A.Поле = 5
Процедура(A)
Debug.WriteLine(A.Поле)
End Sub
Sub Процедура(ByVal
Объект As Класс)
Объект.Поле = 999
End Sub
End Class
По замыслу работы слова ByVal при нажатии кнопки должно было напечататься число 5, но напечатается отчего-то 999. «Значение» переменной A неожиданно изменилось. Происходит это вот почему. При вызове процедуры Процедура значение переменной A копируется в переменную Объект. Но если параметр имеет ссылочный тип, то его значением является ссылка. Получается, что копируется ссылка. Это значит, что переменная A и переменная Объект теперь указывают на одну и ту же область памяти, где хранится значение поля Поле. Раз так, то внутри процедуры Процедура мы можем как угодно менять значение этого поля, что немедленно «почувствует» и переменная A.
То, что здесь сказано, относится, естественно, и к массивам, но не относится к строкам, которые, как я уже говорил, во многом ведут себя, как обычный тип.