VBA数组函数将简单类型的变量转换为值,并且不存储变量引用。但是,如果我传递一个类变量,它将按预期工作。应该是那样的还是我错过了什么?
主模块
Sub test()
Dim collection As collection
Set collection = New collection
Dim i As Long
Dim cl As New tst
i = 25
cl.i = 25
Debug.Print "Original i = " & i
Debug.Print "Original cl.i = " & cl.i
Debug.Print
collection.Add Item:=Array(i)
collection.Add Item:=Array(cl)
Debug.Print "i in array in collection: collection(1)(0) = " & collection(1)(0)
Debug.Print "i from class in array in collection: collection(2)(0).i = " & collection(2)(0).i
Debug.Print
i = i + 1
cl.i = cl.i + 1
Debug.Print "Adding: i = i + 1"
Debug.Print
Debug.Print "Original i = " & i ' 26
Debug.Print "Original cl.i = " & cl.i '26
Debug.Print
Debug.Print "i in array in collection: collection(1)(0) = " & collection(1)(0) '25, but I expect 26
Debug.Print "i from class in array in collection: collection(2)(0).i = " & collection(2)(0).i '26 correct
Debug.Print
End Sub
tst类
Public i As Long
输出
Original i = 25
Original cl.i = 25
i in array in collection: collection(1)(0) = 25
i from class in array in collection: collection(2)(0).i = 25
Adding: i = i + 1
Original i = 26
Original cl.i = 26
i in array in collection: collection(1)(0) = 25
i from class in array in collection: collection(2)(0).i = 26
答案 0 :(得分:4)
是不是应该这样
当然。而且,无论您要传递值还是对象引用,其行为都完全相同。
将i
添加到集合时,会将ByVal
的值(i
)的副本 集合;递增i
不会递增副本。
当您向集合中添加cl
时,该对象的指针(也为ByVal
)的副本 ;修改该指针也不会修改集合中的副本:
Public Sub test()
Dim c As Collection
Set c = New Collection
Dim o As Class1
Set o = New Class1
Debug.Print VarPtr(o), ObjPtr(o)
c.Add o
Debug.Print VarPtr(c(1)), ObjPtr(c(1))
End Sub
此代码输出如下内容:
725937672 221317072
725937528 221317072
请注意,两个指针不同,但是都指向相同的对象引用。
如果我们在本地影响该对象指针的本地副本...
Debug.Print VarPtr(o), ObjPtr(o)
c.Add o
Set o = Nothing
Debug.Print VarPtr(c(1)), ObjPtr(c(1))
Debug.Print VarPtr(o), ObjPtr(o)
现在输出如下:
725937672 221317072
725937528 221317072
725937672 0
我们将o
重新分配给Nothing
,但是集合c
still 引用了该对象!我们根本不影响物体!
您的测试类的Public i
成员从未被复制到任何地方,该集合甚至都不知道/不在乎:所有集合都知道,它持有对对象的引用。
因此,当您执行cl.i = 26
时,就不会分配该集合所知道的任何内容。您只是在说“将对象移到地址X(集合中保存的相同ObjPtr
!,获取其i
属性,并为其赋值26”:该集合的指针副本)从未更新过。
当您执行i = 26
时,您并没有分配该集合所知道的任何信息。您说的是“在地址X(局部变量)处获取变量,为其分配值26”:该值的集合副本从未更新。