对 Visual Basic 中数组的浅拷贝的混淆

Confusion over shallow copies of arrays in Visual Basic

我的理解是,数组的浅拷贝会复制数组变量,因此您有两个指向堆上同一内存位置的指针。但是根据这个逻辑,下面的代码应该可以工作,但它没有:

Sub Main()
    Dim row As Long() = {1, 2, 3, 4}
    ChangeRow(row.Clone)
    Console.WriteLine(row(0))
End Sub

Sub ChangeRow(ByVal array As Long())
    array(0) = 0
End Sub

Clone 方法应该进行浅表复制。这意味着您将指向原始数组的指针作为参数传递。到目前为止,我所阅读的关于该主题的所有内容都指向这段代码有效,但事实并非如此。谁能解释一下?

有问题的方言是VB.Net

My understanding is that a shallow copy of an array copies the array variable, so that you have two pointers to the same memory location on the heap.

没有。它创建了一个 new 容器,其中包含所有相同的项目,并且在其他方​​面与之前的容器相同,但容器本身位于堆上的不同位置。它不会创建对先前容器的重复引用。

您所描述的只是一个参考。考虑这段代码:

Dim row As Long() = {1, 2, 3, 4}
Dim otherRow as Long() = row

程序的内存现在看起来有点像这样:

Clone 确实会创建一个浅拷贝——也就是说,它会创建一个 new 数组,其中包含与原始数组相同的所有值。然后,您在该新数组的第一项设置值,但这不会影响原始数组,因为它们是完全不同的数组,彼此之间没有 运行 时间引用。考虑这段代码:

Dim row As Long() = {1, 2, 3, 4}
Dim otherRow as Long() = row.Clone

程序的内存现在看起来有点像这样:

如果要在 ChangeRow 子程序中修改原始数组,只需不要调用克隆即可。

Sub Main()
    Dim row As Long() = {1, 2, 3, 4}
    ChangeRow(row)
    Console.WriteLine(row(0)) ' outputs 0
End Sub

Sub ChangeRow(ByVal array As Long())
    array(0) = 0
End Sub

为了说明为什么这实际上是一个 'shallow' 副本,请检查它如何与引用类型一起使用。

Class Ref
    Public Value As Long 
    Public Sub New(ByVal value As Long)
        Value = value
    End Sub
End Class

Sub Main()
    Dim row As Ref() = {New Ref(1), New Ref(2), New Ref(3), New Ref(4)}
    ChangeRow(row.Clone)
    Console.WriteLine(row(0).Value) ' outputs 0
End Sub

Sub ChangeRow(ByVal array As Ref())
    array(0).Value = 0
End Sub

即使 rowrow.Clone 引用不同的数组,这些数组中的值(Ref 的实例)是相同的,所以修改 array(0).Value 是与修改 row(0).Value 相同。在这种情况下,程序的内存看起来有点像这样: