我正在努力理解按值传递并在VB6中通过引用传递.我完全理解这些概念是面向对象的编程语言,如.NET和Java(我意识到Java没有通过引用传递).看看下面的代码:
Private Sub Form_Load()
Dim Test As Integer
Test = 1
TestFunction Test 'line 5
MsgBox (Test)
End Sub
Private Sub TestFunction(ByVal i As Integer)
i = i + 1
End Sub
Run Code Online (Sandbox Code Playgroud)
当我在第5行的Test周围放置括号时,消息框会按照我的预期打印1.现在看看下面的代码:
Private Sub Form_Load()
Dim Test As Integer
Test = 1
TestFunction Test 'line 5
MsgBox Test
End Sub
Private Sub TestFunction(ByRef i As Integer)
i = i + 1
End Sub
Run Code Online (Sandbox Code Playgroud)
消息框按照我的预期打印2.但是,如果在第5行添加括号,则消息框将打印1,这是我不希望的.即使被调用函数中定义的变量是ByRef,看起来调用函数也可以通过值传递.反之亦然,即如果被调用函数具有定义为ByVal的变量的签名,则它将始终为ByVal(即使调用函数中的变量周围没有括号).在VB6中,这背后的想法是什么?我意识到这是VB6中的一个基本问题,但它让我很困惑.我已经阅读了MSDN文档,我意识到这一切都是正确的,但它并没有解释它背后的原因.
Mar*_*rkJ 19
这是VB6中的经典问题.它在VB6手册中有解释.在下面的代码中,VB6将参数视为表达式(Test)而不是变量引用
TestFunction (Test)
Run Code Online (Sandbox Code Playgroud)
为了传递对变量的引用,要么省略括号,要么使用遗留Call语句(需要括号)
TestFunction Test
Call TestFunction(Test)
Run Code Online (Sandbox Code Playgroud)
VB6允许您将表达式传递给ByRef参数,即使方法更改它们也是如此.你可以写
TestFunction (Test + 2)
Run Code Online (Sandbox Code Playgroud)
编译器创建一个临时副本并通过引用传递它.VB.Net 以类似的方式使用括号.
如果TestFunction采用如下两个参数,您也可以让编译器创建临时副本:
TestFunction (one), (two)
Run Code Online (Sandbox Code Playgroud)
即使Call您将括号加倍,也可以添加一个额外的不必要的副本,您可以获得临时副本:
Call TestFunction((Test))
Run Code Online (Sandbox Code Playgroud)
将括号内的任何表达式括起来会导致在执行任何其他操作之前首先计算该表达式,即使该表达式只是单个变量也是如此.在您的情况下,该表达式的结果然后作为参数传递.
所以,你实际上是通过引用传递参数.但是你传递的参数是表达式的结果,而不是原始变量.这就是原始变量未更新的原因.