代码之家  ›  专栏  ›  技术社区  ›  tmighty

在.NET中,ByVal和ByRef没有区别吗?[复制品]

  •  2
  • tmighty  · 技术社区  · 6 年前

    这个问题已经有了答案:

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

    但是,我很困惑为什么可以使用byval将winforms控件传递给Sub以更改其某些属性。在很多文章中都使用了“byval”,对此我很困惑。 当Sub确实更改了控件的属性时,我特别困惑。 我在想,当使用“byval”时,这是怎么可能的。 据我所知,如果控件通过ByVal,Sub不应该能够操纵它。

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

    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)确实改变了列表(字符串)。

    调用Sub后,第一项是“test0somechange”。 在我的理解中,只有当列表(字符串)作为“byref”传递时,才会发生这种情况。

    我这里缺什么?

    1 回复  |  直到 6 年前
        1
  •  3
  •   jmcilhinney    6 年前

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

    这样想。假设你有一支球队,乔是那支球队的队长。你需要派人到房间里去执行一项任务。你说“让我们把船长叫进来”,你就把乔叫到房间里去。在房间里,有人让乔脱下他穿的蓝色衬衫,穿上一件红色衬衫,然后他们决定乔可以坐下,实际上他们会让已经在房间里的安德鲁来代替他执行任务。这是否意味着安德鲁现在是你队的队长?当然不是。事实上,他们用不同的人在房间里执行任务,并不影响房间外的任何事情,所以乔仍然是团队的队长。但是当你看到乔走出房间时,他会穿上他们让他穿的那件红衬衫。在房间内对乔本人所做的更改仍会影响到房间外的乔。就是这样 ByVal 在.NET中处理引用类型参数。

    使这个真实的场景像使用 传地址 在.NET中,你必须接受,如果有人在房间里而不是乔来完成任务,他们将成为你团队的队长。这是现实世界中几乎从未发生过的事情,这就是为什么 传地址 是vb.net中的奇怪之处,它是一种面向对象的语言,并且 拜瓦尔 是默认行为。