В чем разница? Я всегда использую ByVal, но, на самом деле, я не очень хорошо знаю, когда мне и когда не...
Разница между ByVal и ByRef?
Ответ 1
Если вы передадите ссылку, когда вы измените значение в методе, переменная на сайте вызова также будет изменена.
Если вы передадите значение, оно будет таким же, как если бы в методе была создана другая переменная, поэтому, даже если вы ее измените, исходная переменная (на сайте вызова) не изменит ее значение.
Итак, вы обычно должны передавать переменные как значение. Передавайте только ссылку, если у вас есть явная необходимость сделать это.
Ответ 2
ByRef = Вы даете своему другу свою бумагу для заметок (оригинал), он отмечает ее и может вернуть ее вам.
ByVal = Вы даете химе копию терминологической бумаги, и он возвращает вам свои изменения, но вы должны вернуть их обратно в свое оригинальное произведение.
Просто, как я могу это сделать.
Зачем использовать Byref:
ByRef передаст POINTER на объект, который вы передаете. Если вы находитесь в одном и том же пространстве памяти, это означает передачу только "слова", а не объекта. Метод, с которым вы его передаете, может вносить изменения в исходный объект и вообще не передавать их обратно, поскольку они находятся в исходном объекте. Полезно для больших объемов данных. Вы также можете использовать ByRef, чтобы разрешить использование SUB, а не FUNCTION (In VB), поскольку ему не нужно передавать объект назад.
Почему бы не использовать Byref:
Поскольку метод имеет доступ к оригиналу, любые сделанные изменения будут немедленными и постоянными. Если метод выходит из строя, отклонение может быть повреждено. Использование ByVal сделает копию, передаст всю копию в метод, а затем метод обработает информацию и либо вернет копию назад, сообщит информацию, либо ничего не сделает.
Ответ 3
ByRef похож на второе возвращаемое значение. Он передает ссылку на объект в функцию, а не сам объект. Если вы измените значение параметра ByRef
в функции, вы увидите эти изменения после завершения функции. Если это не было достаточно ясно, прочитайте это и это.
Ответ 4
Я знаю, что этот вопрос в значительной степени был дан ответ, но я просто хотел добавить следующее...
Объект, который вы передаете функции, зависит от ByRef/ByVal, однако, если этот объект содержит ссылки на другие объекты, они могут быть изменены вызываемым методом независимо от ByRef/ByVal. Плохое объяснение, я знаю, см. Ниже код для лучшего понимания:
Public Sub Test()
Dim testCase As List(Of String) = GetNewList()
ByRefChange1(testCase)
'testCase = Nothing
testCase = GetNewList()
ByValChange1(testCase)
'testCase is unchanged
testCase = GetNewList()
ByRefChange2(testCase)
'testCase contains the element "ByRef Change 2"
testCase = GetNewList()
ByValChange2(testCase)
'testCase contains the element "ByVal Change 2"
End Sub
Public Function GetNewList() As List(Of String)
Dim result As List(Of String) = New List(Of String)
result.Add("Value A")
result.Add("Value B")
result.Add("Value C")
Return result
End Function
Public Sub ByRefChange1(ByRef aList As List(Of String))
aList = Nothing
End Sub
Public Sub ByValChange1(ByVal aList As List(Of String))
aList = Nothing
End Sub
Public Sub ByRefChange2(ByRef aList As List(Of String))
aList.Add("ByRef Change 2")
End Sub
Public Sub ByValChange2(ByVal aList As List(Of String))
aList.Add("ByVal Change 2")
End Sub
EDIT:
Также рассмотрим, была ли вызвана эта функция:
Public Sub ByValChange3(ByVal aList As List(Of String))
aList.Add("ByVal Change 3")
aList = New List(Of String)
aList.Add("ByVal Change 4")
End Sub
Что происходит в этом случае: "ByVal Change 3" добавляется в список вызывающих абонентов, но в точке, где вы указываете, что "aList = Новый список", вы указываете новую ссылку, на новый объект и становитесь отсоединенными из списка вызывавших абонентов. И здравый смысл, и может однажды вас поймать, поэтому нужно иметь в виду.
Ответ 5
Надеюсь, это ответит на ваш вопрос.
Sub last_column_process()
Dim last_column As Integer
last_column = 234
MsgBox last_column
trying_byref x:=last_column
MsgBox last_column
trying_byval v:=last_column
MsgBox last_column
End Sub
Sub trying_byref(ByRef x)
x = 345
End Sub
Sub trying_byval(ByRef v)
v = 555
End Sub
Ответ 6
Подумайте, что в последнем примере может быть опечатка: Последний sub должен быть "byval", а не "byref".:)
Также добавлен оператор msgbox в try_byval, чтобы вы могли понять, что имеется в виду.
Sub begin()
Dim last_column As Integer
last_column = 234
MsgBox "Begin:" & last_column
trying_byref x:=last_column
MsgBox "byref:" & last_column
trying_byval v:=last_column
MsgBox "byval:" & last_column
End Sub
Sub trying_byref(ByRef x)
x = 111
End Sub
Sub trying_byval(ByVal v) '<--not ByRef, that was in sub trying_byref.
v = 222
MsgBox "In Here:" & v
End Sub
Ответ 7
ByRef, одно значение будет иметь 2 адреса
Итак, если x = 80 (80 - значение, а x - адрес, то, например, переменная y также может быть равна 80, и, следовательно, 80 могут быть доступны через x и y)
Ответ 8
Ответы @Tom и @kelloti полезны. Вот пример кода, чтобы проиллюстрировать далее:
Private Function ValMessage(ByVal SomeMessage As String)
SomeMessage = "Val Val Val" ' <-- this variable modification doesn't persist after the function finishes execution
ValMessage = "Some Return Value"
End Function
Private Function RefMessage(ByRef SomeMessage As String)
SomeMessage = "Ref Ref Ref" ' <-- this variable modification persists even after the function finishes execution
RefMessage = "Some Return Value"
End Function
Private Sub DoStuff()
Dim OriginalMessage As String
Dim OtherMessage As String
Dim AnotherMessage As String
OriginalMessage = "Original"
MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Original"
OtherMessage = ValMessage(OriginalMessage)
MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Original"
AnotherMessage = RefMessage(OriginalMessage)
MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Ref Ref Ref" <--- this is the difference when you pass a paramter by reference
End Sub
Ответ 9
Я постараюсь объяснить разницу простыми словами.
-
передача аргумента по значению делает его входным параметром. Это самый безопасный способ, поэтому он используется по умолчанию в 95% случаев.
-
Передача аргумента по ссылке делает его входным и выходным параметром. Выходной параметр может быть изменен внутри функции, которая создает побочный эффект, который редко используется 5%.