ByVal和ByRef之间的区别?

Vol*_*ort 18 function vb.net-2010

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

小智 12

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

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

就像我能做到的那样简单.

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

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

  • 我几乎完全不同意.使用ByVal不会复制对象.它创建一个指向*same*object.n的新引用.您无法对原始引用执行任何操作,但您可以修改该对象.尝试将新引用设置为空不会释放对象,因为先前的引用仍然存在(这使得对象在GC的眼睛中保持活动) (2认同)

Bru*_*ant 10

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

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

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

  • 我认为这非常重要的是要注意尽管原始对象在通过byval时无法更改,但它的子成员可以是 (6认同)
  • 确实,Smudge202,这很重要……你可以改变对象成员(或者,换句话说,你可以改变对象)。你不能改变的是引用,这意味着你不能用新对象或空值替换对象。 (2认同)

kel*_*oti 5

ByRef就像是第二个返回值.它将对象的引用传递给函数而不是对象本身.如果更改函数中ByRef参数的值,您将在函数结束后看到这些更改.如果这还不够清晰,阅读这个.


Smu*_*202 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
Run Code Online (Sandbox Code Playgroud)

编辑:

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

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
Run Code Online (Sandbox Code Playgroud)

在这种情况下会发生的情况是"ByVal Change 3"被添加到调用者列表中,但是在您指定"aList = New List"时,您将新引用指向新对象,并与调用者分离名单.常识和可能有一天会让你失望,所以要记住一些事情.