ByVal和ByRef之间的区别?

时间:2011-02-05 18:20:52

标签: function vb.net-2010

有什么区别?我总是使用ByVal,但是,我真的不知道我何时应该何时不...

9 个答案:

答案 0 :(得分:11)

ByRef =你给你的朋友你的学期论文(原文),他将其标记出来并将其归还给你。

ByVal =你给hime一份学期论文的副本,然后他会把你的修改还给你,但你必须把它们放回原来的版本中。

尽可能简单。

为什么要使用Byref:
ByRef会将POINTER传递给您传递的对象。如果你在同一个内存空间,这意味着只传递'word'而不是对象。传递给它的方法可以在原始对象中进行更改,而不需要将它们传递回原始对象中。有助于更快地进行大数据传递。您也可以使用ByRef来允许使用SUB而不是FUNCTION(在VB中),因为它不需要传回对象。

为什么不使用Byref:
由于该方法可以访问原始方法,因此所做的任何更改都将是即时和永久的。如果该方法失败,则该oblect可能已损坏。使用ByVal将制作副本,将整个副本传递给方法,然后metod将处理信息并返回副本,报告信息或不执行任何操作。

答案 1 :(得分:10)

如果传入引用,则在修改方法中的值时,也会修改调用站点中的变量。

如果传递值,则与在方法中创建另一个变量的情况相同,因此即使您修改它,原始变量(在呼叫站点)也不会更改其值。

所以,实际上,您通常应该将变量作为值传递。如果您明确需要,请仅作为参考传递。

答案 2 :(得分:5)

ByRef就像是第二个返回值。它将对象的引用传递给函数而不是对象本身。如果更改函数中ByRef参数的值,您将在函数结束后看到这些更改。如果不够明确,read thisthis

答案 3 :(得分:5)

我知道这个问题已经得到了很好的解答,但我只想添加以下内容......

传递给函数的对象受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

编辑:

另外,请考虑是否调用了此函数:

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”时,您将新引用指向新对象,然后变为分离来自来电者名单。无论是常识还是有一天都会让你失望,所以要记住一些事情。

答案 4 :(得分:0)

我希望这能回答你的问题

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

答案 5 :(得分:0)

认为最后一个样本中可能存在拼写错误: 最后一个子应该是" byval"而不是" byref"。 :)

还在trying_byval中添加了一个msgbox语句,以便您了解其含义。

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

答案 6 :(得分:0)

ByRef,一个值将有2个地址

因此,如果x = 80(80是值,x是地址,那么例如变量y也可以是80,因此可以通过x和y访问80)

答案 7 :(得分:0)

@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

答案 8 :(得分:0)

我将尝试用简单的单词来解释差异。

  • 按值传递参数使其仅输入参数。这是最安全的方法,因此在95%的情况下默认使用。

  • 通过引用传递
  • 参数使它既是输入参数又是输出参数。可以在函数内部更改输出参数,这会产生很少使用的副作用。