我有一个带有数组字符串的Sub作为参数:
Private Sub des(ByVal array() As String)
Dim i As Integer
For i = 0 To UBound(array)
array(i) = "hy"
Next
End Sub
当我在main函数中调用函数时,即使数组传递给函数ByVal,str的值也会改变:
Dim str() As String
str = {"11111", "22222", "33333", "44444", "5555", "66666"}
des(str)
我尝试在Sub中制作数组的副本,但它仍然在主函数中更改。
Private Sub des(ByVal array() As String)
Dim i As Integer
Dim array2() As String
array2 = array
For i = 0 To UBound(array)
array(i) = "hy"
Next
End Sub
我在网站上看到你无法传递数组ByVal。这是真的?如果是这样,我该怎么办?
答案 0 :(得分:1)
我在网站上看到你无法传递数组ByVal。这是真的吗?
不,那不是真的。
.NET框架中的数组是引用类型。创建数组时,将创建System.Array
的对象,并将其引用分配给引用变量。
调用des
方法时,将传递数组对象的引用。在des
方法中,ByVal参数是类型System.Array
的引用参数变量,它接收数组对象的引用副本。
MSDN文章 - Passing Arguments by Value and by Reference (Visual Basic)
答案 1 :(得分:1)
试试这个:
Dim i As Integer
Dim array2() As String
array2 = array.Clone()
For i = 0 To UBound(array2)
array2(i) = "hy"
Next
关键区别是.Clone()
,它实际上是数组的浅表副本,而更改array2中的值将不再影响主代码中的str
值。
答案 2 :(得分:1)
数组是引用类型。这意味着当您将数组传递给函数时,传递的内容始终是引用,而不是数组的副本。函数中的数组引用与调用代码中的数组相同的数组对象。
当您在第二个示例中执行assign(它是不副本!)时会发生同样的事情:您所做的只是对同一个对象进行另一次引用。这就是为什么Boeckm的解决方案有效 - Clone()
调用执行创建一个新数组并为其分配值,这些值是原始数组中值的副本。
答案 3 :(得分:1)
在Visual Basic .NET中,关于数组作为参数,您必须注意两个重要规则:
数组本身可以作为ByVal和ByRef传递。
始终可以从函数或子例程中修改数组元素。
您已经知道可以修改子进程(子例程或函数)中数组的元素,无论该数组如何定义为该子进程内的参数。
所以,给定这两个子程序:
Private Sub desval(ByVal array() As String)
array = {}
End Sub
Private Sub desref(ByRef array() As String)
array = {}
End Sub
这个非常简单的辅助子程序(这里我将使用控制台):
Private Sub printArr(ByVal array() As String)
For Each str In array
Console.WriteLine(str)
Next
End Sub
你可以做这些简单的测试:
Dim arr1() as String = {"abc", "xyz", "asdf"}
Console.WriteLine("Original array:")
printArr(arr1)
Console.WriteLine()
Console.WriteLine("After desval:")
desval(arr1)
printArr(arr1)
Console.WriteLine()
Console.WriteLine("After desref:")
desref(arr1)
printArr(arr1)