要么将工作,但对于语义正确的代码,更愿意通过值(ByVal
)传递。
当你按值传递的对象变量,你传递副本指针对象的。
那么,什么程序正在与是同一个对象(即改变属性值将调用者可以看到),但它不能够给Set
指针到别的东西 - 以及它可以,但它会在自己的副本上这样做,因此呼叫者不会受到影响。
Public Sub DoSomething()
Dim target As Worksheet
Set target = ActiveSheet
Debug.Print ObjPtr(target)
DoSomethingElse target
Debug.Print ObjPtr(target)
End Sub
Private Sub DoSomethingElse(ByVal target As Worksheet)
Debug.Print ObjPtr(target)
Set target = Worksheets("Sheet12")
Debug.Print ObjPtr(target)
'in DoSomething, target still refers to the ActiveSheet
End Sub
在另一方面...
Public Sub DoSomething()
Dim target As Worksheet
Set target = ActiveSheet
Debug.Print ObjPtr(target)
DoSomethingElse target
Debug.Print ObjPtr(target)
End Sub
Private Sub DoSomethingElse(ByRef target As Worksheet)
Debug.Print ObjPtr(target)
Set target = Worksheets("Sheet12")
Debug.Print ObjPtr(target)
'in DoSomething, target now refers to Worksheets("Sheet12")
End Sub
一般而言,参数应按值传递。这只是一个不幸的语言怪癖ByRef
是默认的(VB.NET固定的)。
也是如此非对象变量:
Public Sub DoSomething()
Dim foo As Long
foo = 42
DoSomethingElse foo
End Sub
Private Sub DoSomethingElse(ByVal foo As Long)
foo = 12
'in DoSomething, foo is still 42
End Sub
而且......
Public Sub DoSomething()
Dim foo As Long
foo = 42
DoSomethingElse foo
End Sub
Private Sub DoSomethingElse(ByRef foo As Long)
foo = 12
'in DoSomething, foo is now 12
End Sub
如果一个变量是通过引用传递,但在过程的主体是永远不会重新分配,那么它可以通过值传递。
如果变量通过引用传递,并重新分配它在一个过程的主体,则该程序可有可能被写为一个Function
,实际上返回修改后的值来代替。
如果一个变量是按值传递的,并且在过程的主体中被重新分配,那么调用者不会看到变化 - 这会使代码变得可疑;如果一个程序需要重新分配ByVal
参数值,如果它定义了自己的局部变量和分配代码的意图逐渐明朗的是中代替ByVal
参数:
Public Sub DoSomething()
Dim foo As Long
foo = 42
DoSomethingElse foo
End Sub
Private Sub DoSomethingElse(ByVal foo As Long)
Dim bar As Long
bar = foo
'...
bar = 12
'...
End Sub
这些都是实际代码检查在Rubberduck,因为VBE插件,我积极参与了,可以分析你的代码,看到这些东西:
参数通过值传递,但被分配了新的值/引用。如果调用者不应该知道新值,请考虑制作本地副本。如果调用者应该看到新的值,那么该参数应该传递给ByRef,而你有一个错误。
http://rubberduckvba.com/Inspections/Details/AssignedByValParameterInspection
仅具有一个参数由在程序退出之前分配一个新的值/参考引用传递的过程中,使用ByRef参数作为返回值:考虑将其作为一个函数。
http://rubberduckvba.com/Inspections/Details/ProcedureCanBeWrittenAsFunctionInspection
,其通过引用传递和没有被分配一个新的值/参考的参数,可以通过值替代地通过。
http://rubberduckvba.com/Inspections/Details/ParameterCanBeByValInspection
这就是wsReport
这里的情况:
这可能有助于http://www.windowsdevcenter.com/pub/a/oreilly/windows/ ron/objects.html –