.NET中的ByVal和ByRef有什么区别?

时间:2019-01-17 01:47:18

标签: vb.net winforms frameworks

我熟悉ByVal和ByRef之间的区别。

但是,我很困惑为什么我可以使用ByVal将WinForms控件传递给子项以更改其某些属性。在很多文章中都使用了“ ByVal”,对此我感到困惑。 当子实际上确实更改了控件的属性时,我特别困惑。 我想知道当使用“ ByVal”时怎么可能。 以我的理解,如果子控件传递了ByVal,则该子控件应该无法对其进行操作。

为了进一步测试,我运行了以下测试代码:

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim n As New List(Of String)

        n.Add("test0")

        pAlterList(n)

        Debug.Assert(n(0) = "test0")

    End Sub

    Private Sub pAlterList(ByVal u As List(Of String))

        u(0) = u(0) & "somechange"

    End Sub

End Class

奇怪的是pAlterList(即使它使用ByVal)也会更改List(字符串)。

在调用该子项之后,第一项是“ test0somechange”。 据我了解,只有在将List(Of String)作为“ ByRef”传递时,这种情况才会发生。

我在这里想念什么?

1 个答案:

答案 0 :(得分:3)

您缺少的是,对于引用类型,ByRef仅影响将新对象分配给参数是否影响原始变量,而不影响对参数所引用的对象进行更改是否影响原始变量。变量。

这样想。假设您有一个团队,而Joe是该团队的队长。您需要派人进入一个房间来执行任务。您说“让队长送他们进来”,所以您让Joe送他进入房间。在房间里,有人要求乔脱下他穿着的蓝色衬衫并穿上红色的衬衫,然后他们决定让乔可以坐下,然后实际上是让已经在房间里的安德鲁来执行任务。 。这是否意味着安德鲁现在是您球队的队长?当然不是。他们使用不同的人在房间内执行任务这一事实不会影响房间外的任何事物,因此Joe仍然是团队的队长。但是,当您看到乔走出房间时,他将穿着他们要求他穿的红色衬衫。在房间内对Joe自己所做的更改仍然会影响房间外的Joe。这就是ByVal在.NET中对引用类型参数进行工作的方式。

要使这种现实情况像在.NET中使用ByRef一样工作,您必须接受,如果其他人而不是Joe在房间内执行任务,他们将成为您团队的队长。那是现实世界中几乎从未发生过的事情,这就是为什么ByRef是OO语言VB.NET中的奇怪之处,而ByVal是默认行为。