Насколько я понимаю, поверхностная копия массива копирует переменную массива, поэтому у вас есть два указателя на одну и ту же область памяти в куче.
Нет.Он создает новый контейнер, содержащий все те же элементы и в остальном идентичный предыдущему контейнеру, но сами контейнеры находятся в разных местах в куче.Он не создает дублирующую ссылку на предыдущий контейнер.
То, что вы описываете, является просто ссылкой.Рассмотрим этот код:
Dim row As Long() = {1, 2, 3, 4}
Dim otherRow as Long() = row
Память программы теперь выглядит примерно так:
Clone
действительно создаст поверхностную копию, то есть он создаст новый массив, который содержит все те же значения, что и исходный массив.Затем вы устанавливаете значение для первого элемента в этом новом массиве, но это не повлияет на оригинал, потому что это совершенно разные массивы без ссылок друг на друга во время выполнения.Рассмотрим этот код:
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
Чтобы проиллюстрировать, почему это на самом деле «мелкая» копия, посмотрите, как это работает с ссылочными типами.
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
Даже если row
и row.Clone
относятся к разным массивам, значения в этих массивах (экземпляры Ref
) одинаковы, поэтому изменение array(0).Value
аналогично изменению row(0).Value
.В этом случае память программы выглядит примерно так: