请参阅以下代码:
Public Class TypeTest
Public variable1 As String
End Class
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim t1 As TypeTest = New TypeTest
Test(t1)
MsgBox(t1.variable1)
End Sub
Public Sub Test(ByVal t1 As TypeTest)
t1.Variable1 = "Thursday"
End Sub
End Class
form_load中的消息框打印:星期四,这意味着对象(TypeTest)通过引用传递。 在函数调用中使用ByVal和ByRef作为t1争论有什么区别:Test。
答案 0 :(得分:16)
由于您将TypeTest
声明为Class
,因此将其设为引用类型(而不是Structure
,用于声明值类型)。引用类型变量充当对象的指针,而值类型变量直接存储对象数据。
您的理解是正确的,ByRef
允许您更改参数变量的值,而ByVal
则不允许。使用值类型时,ByVal
和ByRef
之间的差异非常明显,但是当您使用引用类型时,行为的预期会少一些。您可以更改引用类型对象的属性值的原因,即使它被传递ByVal
,是因为变量的值是对象的指针,而不是对象本身。更改对象的属性根本不会更改变量的值。该变量仍包含指向同一对象的指针。
这可能会让您相信参考类型ByVal
和ByRef
之间没有区别,但事实并非如此。它们是有区别的。不同之处在于,当您将引用类型参数传递给ByRef
参数时,您正在调用的方法可以更改原始变量所指向的对象。换句话说,该方法不仅能够改变对象的属性,而且还能够将参数变量完全指向另一个对象。例如:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim t1 As TypeTest = New TypeTest
t1.Variable1 = "Thursday"
TestByVal(t1)
MsgBox(t1.variable1) ' Displays "Thursday"
TestByRef(t1)
MsgBox(t1.variable1) ' Displays "Friday"
End Sub
Public Sub TestByVal(ByVal t1 As TypeTest)
t1 = New TypeTest()
t1.Variable1 = "Friday"
End Sub
Public Sub TestByRef(ByRef t1 As TypeTest)
t1 = New TypeTest()
t1.Variable1 = "Friday"
End Sub
答案 1 :(得分:4)
还有一些例子。一个显示ByRef强制ByVal
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim tt As TypeTest = New TypeTest
tt.variable1 = "FooBar"
Debug.WriteLine("'1 " & tt.variable1)
TestByVal1(tt)
Debug.WriteLine("'2.1 " & tt.variable1)
tt.variable1 = "FooBar"
TestByVal2(tt)
Debug.WriteLine("'2.2 " & tt.variable1)
tt.variable1 = "FooBar"
TestByRef(tt)
Debug.WriteLine("'3 " & tt.variable1)
tt.variable1 = "FooBar"
TestByRef((tt)) 'note inner set of () force ref to val
Debug.WriteLine("'4 " & tt.variable1)
'debug output
'1 FooBar
'2.1 FooBar
'2.2 Monday
'3 Friday
'4 FooBar
End Sub
Public Sub TestByVal1(ByVal t1 As TypeTest)
t1 = New TypeTest()
t1.variable1 = "Monday"
End Sub
Public Sub TestByVal2(ByVal t1 As TypeTest)
t1.variable1 = "Monday"
End Sub
Public Sub TestByRef(ByRef t1 As TypeTest)
t1 = New TypeTest()
t1.Variable1 = "Friday"
End Sub
答案 2 :(得分:1)
ByVal实际上复制当前变量的值并将其传递给函数。通过引用复制当前对该函数的引用。我们举个例子:
t1是一个引用变量,它包含TypeTest类型的对象的地址,因此当您使用ByVal时,地址将被复制到该函数中。最终你使用相同的对象。
真正有意义的是,在基本变量如int,float等的情况下。
示例:Int temp = 0;
temp是一个包含值0的变量,因此当复制0时会传递。如果使用引用,则将temp的地址传递(& 0)到函数。
总而言之,ByRef仅在基本类型而非复杂类型中更有意义。