参数将ByVal传递给VB.NET函数并在那里进行操作

时间:2014-05-04 18:29:08

标签: vb.net arguments task-parallel-library byref byval

在此Microsoft示例中,使用MultiplyMatricesSequential(...)修饰符作为参数结果将一个双精度数组传递给函数MultiplyMatricesParallel(...)ByValhttp://msdn.microsoft.com/de-de/library/dd460713(v=vs.110).aspx

在这些函数中正在修改数组中的值,并且在调用函数返回后可以使用这些更改。 当我在函数ByVal中将ByRef更改为MultiplyMatricesSequential(...)时没有任何更改,当我在第二个函数中更改为ByRef时,IDE抱怨在Lambda表达式中被操纵的参数无法通过参考

我现在想知道在强制使用ByVal时,调用者的数组值是如何变化的?

2 个答案:

答案 0 :(得分:1)

将对象ByVal传递给函数时,会在堆栈上放置指向它的指针。然后函数可以修改对象的内部部分,但不能用新对象替换它。

当您传递一个ByRef对象时,您会在堆栈上放置指向对象指针的指针。该函数现在可以用新的对象替换整个对象。

如果您将一个内在值(如Int32)发送到函数ByVal,则该值将被放入堆栈中,并且该函数根本无法对其进行编辑。

答案 1 :(得分:0)

区别在于“值类型”和“引用类型”。值类型定义为“结构”(VB.NET)或“结构”(C#),而引用类型定义为“类”。整数类型(如整数,双精度和布尔值)是值类型。数组是引用类型。正如@MattiasÅslund指出的那样,无论是通过ByVal还是ByRef传递,你都会使用引用类型传递一个指针。

如果您确实想要操作传递的数组但是将原始数组返回给调用过程,则需要复制到新的本地声明的数组中。但是,如果传递非常大的数组,请注意开销。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim myOriginalArray As String() = New String() {"Hello", "to", "you", "Michael"}
    ManipulateArray(myOriginalArray)
    MessageBox.Show("myOriginalArray = " & myOriginalArray(0) & " " & myOriginalArray(1) & " " & myOriginalArray(2) & " " & myOriginalArray(3))
End Sub

Private Sub ManipulateArray(ByVal myOriginalArray As String())
    Dim myCopyArray(myOriginalArray.GetUpperBound(0)) As String
    myOriginalArray.CopyTo(myCopyArray, 0)
    myCopyArray(3) = "Sarah"
    MessageBox.Show("myCopyArray = " & myCopyArray(0) & " " & myCopyArray(1) & " " & myCopyArray(2) & " " & myCopyArray(3))
End Sub