Разница между Как byval и byref?
в чем разница? Я всегда использую ByVal, но у меня нет хорошего представления о том, когда я должен, а когда нет...
8 ответов
Если вы передаете ссылку, при изменении значения в методе переменная на сайте вызовов также будет изменена.
Если вы передаете значение, это то же самое, как если бы другая переменная была создана в методе, поэтому, даже если вы измените ее, исходная переменная (на сайте вызова) не изменит свое значение.
Так, в самом деле, вы должны, как правило, проходят переменные, как ценность. Пройти только как ссылку, если у вас есть явная необходимость.
ByRef = вы отдаете своему другу свою курсовую работу (оригинал), он помечает ее и может вернуть ее вам.
ByVal = вы даете ему копию курсовой работы, и он возвращает вам свои изменения, но вы должны вернуть их в свой оригинал самостоятельно.
как можно проще.
зачем использовать Byref:
ByRef передаст указатель на объект, который вы передаете. Если вы находитесь в одном и том же пространстве памяти, это означает передачу только "слова", а не объект. Метод, которому вы его передаете, может вносить изменения в исходный объект и не должен передавать их обратно, как они есть в исходном объекте. Полезно для ускорения передачи больших данных. Вы также можете использовать ByRef, чтобы разрешить использование SUB, а не функции (в VB), поскольку ей не нужно возвращать объект.
Почему бы не использовать Byref:
Поскольку метод имеет доступ к оригиналу, сделанные изменения будут немедленными и постоянными. Если метод терпит неудачу, то oblect может быть поврежден. Использование ByVal сделает копию, передаст всю копию в метод, а затем метод обработает информацию и либо перезапустит копию, сообщит информацию, либо ничего не сделает.
ByRef - это как второе возвращаемое значение. Он передает ссылку на объект в функцию, а не сам объект. Если вы измените значение ByRef
параметр в функции, вы увидите эти изменения после завершения функции. Если это было недостаточно ясно,читать это и этой.
Я знаю, что на этот вопрос в значительной степени был дан ответ, но я просто хотел добавить следующее...
объект, который вы передаете функции, подлежит 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 = New List", вы указываете новую ссылку на новый объект и отсоединяетесь от списка вызывающих. И здравый смысл, и может настигнуть вас однажды, поэтому что-то нужно иметь в виду.
надеюсь, это ответит на ваш вопрос
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
думаю, что в последнем примере могла быть опечатка: Последний суб должен быть "byval", а не"byref". :)
также добавлен оператор msgbox в trying_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
ByRef, одно значение будет иметь 2 адреса
Итак, если x=80 (80-значение и x-адрес, то, например, переменная y также может быть 80, и, следовательно, 80 может быть доступна x и y)
ответы @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