为啥 ByRef 不能与 WithEvents 一起使用?
Posted
技术标签:
【中文标题】为啥 ByRef 不能与 WithEvents 一起使用?【英文标题】:Why does ByRef not work in conjunction with WithEvents?为什么 ByRef 不能与 WithEvents 一起使用? 【发布时间】:2013-07-02 08:37:33 【问题描述】:我想我很清楚VB中ByVal
和ByRef
之间的区别是什么,但我的问题是当我尝试将它与WithEvents
声明的成员一起使用时。
我有以下方法:
Private Sub SafeCloseAndDeRefConnection(ByRef cnx As ADODB.Connection)
On Error GoTo ErrH
If Not cnx Is Nothing Then
If (cnx.State And adStateConnecting) = adStateConnecting Then
cnx.Cancel
End If
If (cnx.State And adStateOpen) = adStateOpen Then
cnx.Close
End If
Set cnx = Nothing
End If
Exit Sub
ErrH:
Set cnx = Nothing
End Sub
如果我有一个这样声明的类成员:
Private WithEvents Connection As ADODB.Connection
然后我想关闭连接,然后这样调用它:
SafeCloseAndDeRefConnection Connection
但在调用SafeCloseAndDeRefConnection
之后,Connection
变量没有设置为Nothing
,并且仍然具有其原始引用。
如果我删除 WithEvents
关键字,则对 SafeCloseAndDeRefConnection
的调用将按预期工作(但显然无法处理事件)
谁能向我解释为什么会这样?
附:我找到了一个类似的question elsewhere,但解决方法在我的场景中不起作用。
【问题讨论】:
无法传递WithEvents
对象ByRef
,如果您尝试它,则传递“副本”,就像您声明它ByVal
一样。它必须以这种方式来管理连接和断开实际对象的传出事件接口和客户端的接收器对象。
尝试实现一个“流利的”功能,然后你可以像这样使用它Set Connection = SafeCloseAndDeRefConnection(Connection)
@Bob77 感谢您的回复。这有点道理(尽可能多的 VB 可以说得通)。您是否有更详细解释的参考? VB6 是一种“Web 2.0 之前的”语言,因此这方面的帮助有些分散,在网络上也不容易找到。
该机制的细节是Windows主题,而不是VB6主题。 VB6 努力消除了解此类实现细节的需要。您可以在msdn.microsoft.com/en-us/library/windows/desktop/… 尝试“COM 和可连接对象中的事件”
【参考方案1】:
或许调用:
Set Connection = Nothing
SafeCloseAndDeRefConnection(Connection)
之后
这将强制销毁对象,而不是依赖VB6为你做!
【讨论】:
有点违背了该方法最初存在的目的。以上是关于为啥 ByRef 不能与 WithEvents 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
optional [byval byref] [paramarray] 变量名() as 数据类型
VBA ByRef Argument Type Mismatch string into string
在运行时测试传入的 ByRef 参数是不是与给定的“其他”变量共享存储位置