Разница между Как 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