Difference between ByVal and ByRef?

我只是一个虾纸丫 提交于 2020-01-09 19:47:29

问题


What is the difference? I always use ByVal, but, I don't really have a good idea of when should I and when not...


回答1:


If you pass in a reference, when you modify the value in the method, the variable in the call site will also be modified.

If you pass value, it's the same as if another variable is created at the method, so even if you modify it, the original variable (at the call site) won't have its value changed.

So, indeed, you should usually pass variables as value. Only pass as reference if you have an explicit need to do so.




回答2:


ByRef = You give your friend your term paper (the original) he marks it up and can return it to you.

ByVal = You give hime a copy of the term paper and he give you back his changes but you have to put them back in your original yourself.

As simple as I can make it.

Why to use Byref:
ByRef will pass the POINTER to the object you are passing. If you are in the same memory space, this means passing just the 'word' not the object. The method you are passing it to can make changes in the origuinal object, and does not need to pass them back at all, as they are in the original object. Useful for making large data passes faster. You can also use ByRef to allow use of a SUB rather then a FUNCTION (In VB) since it does not need to pass back the object.

Why Not to Use Byref:
Since the method has access to the original, anychanges made will be immediate and permanent. If the method fails, the oblect could be corrupted. Using ByVal will make a copy, pass the whole copy into the method, and then the metod will process the info and either retunr a copy back, report information or do nothing.




回答3:


ByRef is like a second return value. It passes a reference to the object into the function rather than the object itself. If you change the value of a ByRef parameter in the function, you will see those changes after the function ends. If that wasn't clear enough, read this and this.




回答4:


I know this question has pretty much been answered, but I just wanted to add the following...

The object you pass to a function is subject to ByRef/ByVal, however, if that object contains references to other objects, they can be modified by the called method regardless of ByRef/ByVal. Poor explanation, I know, see code below for a better understanding:

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:

Also, consider if this function was called:

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

What happens in this case is "ByVal Change 3" is added to the callers list, but at the point you specify that "aList = New List" you are then pointing the new reference, to a new object, and become detached from the callers list. Both common sense and might catch you out one day, so something to bear in mind.




回答5:


I hope this answers your question

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:


Think there may have been a typo in the last sample: The last sub should be "byval" and not "byref". :)

Also added a msgbox statement in trying_byval so you can understand what is meant.

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, one value will have 2 addresses

So if x=80 (80 is value and x is address, then for example variable y can be 80 as well, and thus 80 can be accessed by x and y)




回答8:


Answers by @Tom and @kelloti are helpful. Here's a code example to illustrate further:

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:


I will try to explain the difference in simple words.

  • passing argument by value makes it input only parameter. This is the safest way, therefore is used by default in 95% of the cases.

  • passing argument by reference makes it both input and output parameter. The output parameter can be changed inside the function which creates a rarely used side-effect.



来源:https://stackoverflow.com/questions/4908692/difference-between-byval-and-byref

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!