2012-02-06 48 views
2

我有一个字符串数组作为参数子:子/功能数组参数改变

Private Sub des(ByVal array() As String) 

    Dim i As Integer 

    For i = 0 To UBound(array) 
     array(i) = "hy" 
    Next 

End Sub 

当我打电话给我的主要功能内部的功能,即使在阵列被传递到的STR的值变化函数ByVal:

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。这是真的?如果是这样,我该如何继续?

回答

1

我在一个网站上阅读,你不能传递数组ByVal。这是真的?

不,那不是真的。

在.NET框架数组是一种引用类型。当创建一个数组,将创建的System.Array对象及其引用被分配给参考变量。

当调用一个方法des,阵列对象的引用将被传递。在des方法,BYVAL参数是System.Array类型的参考参数变量,它接收的阵列对象的参考副本。

MSDN文章 - Passing Arguments by Value and by Reference (Visual Basic)

1

试试这个:

Dim i As Integer 

    Dim array2() As String 
    array2 = array.Clone() 

    For i = 0 To UBound(array2) 
     array2(i) = "hy" 
    Next 

的主要区别是.Clone(),这实际上使阵列的浅拷贝,并在数组2改变值将不再影响在主代码的str值。

1

数组是引用类型。这意味着,当你传递一个数组给你的函数,什么传递始终是一个参考,而不是数组的一个副本。在函数数组是指相同的数组对象作为调用代码的阵列。

当您在第二个示例中进行赋值(它是而不是副本!)时,会发生同样的事情:您完成的所有操作都是对同一个对象进行另一次引用。这就是为什么Boeckm的解决方案进行的 - Clone()呼叫作出新的阵列,并为其分配值这是原始数组中的值的副本。

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 

这很简单辅助子程序(这里我将使用Console):

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)