子/函数数组参数已更改

时间:2012-02-06 14:10:16

标签: vb.net

我有一个带有数组字符串的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。这是真的?如果是这样,我该怎么办?

4 个答案:

答案 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)