Насколько я помню, всегда были проблемы с параметрами ByVal
и ByRef
/ ref
.Вот лучший способ, которым я могу это объяснить:
Вам нужно только передать объект по ссылке тогда и только тогда, когда вы планируете заменить эту ссылку на другая ссылка.Если вы хотите изменить содержимое передаваемого объекта, вам нужно только передать его по значению.Пример:
Public Class Person
Public Property FirstName As String
Public Property LastName As String
End Class
Public Shared Sub ModifyPerson(ByVal someone As Person)
' Passed by value ^^^^^
someone.LastName = "Doe"
End Sub
Public Shared Sub Main(ByVal args() As String)
Dim me As New Person
me.FirstName = "Adam"
me.LastName = "Maras"
ModifyPerson(me)
Console.WriteLine(me.LastName) ' Writes "Doe"
End Sub
Да, экземпляр Person
с именем me
передается в ModifyPerson
по значению ;это просто означает, что ссылка на экземпляр передается по значению.Функция все еще может изменять элементы этой ссылки.Теперь попробуйте следующее:
Public Shared Sub Main(ByVal args() As String)
Dim me As New Person
me.FirstName = "Adam"
me.LastName = "Maras"
AssignByValue(me)
Console.WriteLine(me.LastName) ' Writes "Maras"
AssignByReference(me)
Console.WriteLine(me.LastName) ' Writes "Doe"
End Sub
Public Shared Sub AssignByValue(ByVal someone As Person)
Dim new As New Person
new.FirstName = "John"
new.LastName = "Doe"
someone = new
End Sub
Public Shared Sub AssignByReference(ByRef someone As Person)
Dim new As New Person
new.FirstName = "John"
new.LastName = "Doe"
someone = new
End Sub
Эти функции отличаются, поскольку они пытаются изменить фактическую передаваемую ссылку. AssignByValue
не влияет на Person
с именем me
, поскольку параметр передаетсязначение.Однако AssignByReference
может изменить значение этого параметра в методе, который его вызвал, поэтому второй вызов Console.WriteLine(me.LastName)
отражает обновленную ссылку.