Подтвердить что ты не робот

Разница между ByVal и ByRef?

В чем разница? Я всегда использую ByVal, но, на самом деле, я не очень хорошо знаю, когда мне и когда не...

4b9b3361

Ответ 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%.