Excel 我可以对任何对象进行强制转换';什么是默认接口?
我知道在VBA中,所有类都公开一个默认接口(这只是类模块的名称)。您还可以让他们Excel 我可以对任何对象进行强制转换';什么是默认接口?,excel,vba,interface,reference,Excel,Vba,Interface,Reference,我知道在VBA中,所有类都公开一个默认接口(这只是类模块的名称)。您还可以让他们实现另一个自定义界面;为类提供一些属性,这些属性从自定义接口的角度来看是可见的,但从默认接口看不到 我有一个方法,它需要实现某个接口的类 Public Sub doStuff(ByVal item As ICustomInterface) 像 Dim a As New Class1 'Implements ICustomInterface Dim b As New Class2 'Implements ICusto
实现另一个自定义界面
;为类提供一些属性,这些属性从自定义接口的角度来看是可见的,但从默认接口看不到
我有一个方法,它需要实现某个接口的类
Public Sub doStuff(ByVal item As ICustomInterface)
像
Dim a As New Class1 'Implements ICustomInterface
Dim b As New Class2 'Implements ICustomInterface too
doStuff a
doStuff b
doStuff New Collection 'raises "runtime error 13 - type mismatch" as Collection doesn't implement ICustomInterface
如果我理解正确,当我向该方法提供对象实例时,通过将引用传递给该对象的默认接口,VBA查询该对象实例以生成对该对象的ICustomInterface
的引用,并将新引用存储在项
变量中。我认为这个过程叫做向下投射
我的问题是doStuff
调用的方法需要传递item的默认接口,而不是自定义接口。
为了演示,我们可以使用
ObjPtr
来识别所指向的接口:
Dim implementation As Object
Dim defaultCast As Class1 'implements ICustomInterface
Dim downCast As ICustomInterface
Set implementation = New Class1 'or Class2 - store reference to default interface in variable
'1) Check if implementation indeed points to default interface
Set defaultCast = implementation
Debug.Assert ObjPtr(defaultCast) = ObjPtr(implementation) 'fine
'2) Check if down-casting gives different interface
Set downCast = implementation
Debug.Assert ObjPtr(downCast) <> ObjPtr(implementation) 'fine
'4) Check if casting from ICustomInterface to Object reverts to default interface
Dim objectUpCast As Object
Set objectUpCast = downCast
Debug.Assert ObjPtr(objectUpCast) = ObjPtr(implementation) 'fails :(
Debug.Assert ObjPtr(objectUpCast) = ObjPtr(downCast) 'succeeds - not what I want
'3) Check if casting from ICustomInterface to Class1 reverts to Class1's default interface
Dim strictUpCast As Class1
Set strictUpCast = downCast
Debug.Assert ObjPtr(strictUpCast) = ObjPtr(implementation) 'fine - but won't work if I Set implementation = New Class2
'/some other implementation of the ICustomInterface
但我更喜欢在我的函数签名中检查类型,然后在需要时向上转换回默认界面的工作流程只需先转换为IUnknown:
Dim objectUpCast As Object
Dim iUnk As IUnknown
Set iUnk = downCast
Set objectUpCast = iUnk
编辑
所有VB接口都是双接口,这意味着所有接口都源自IDispatch,而IDispatch又源自IUnknown
请注意,对象数据类型代表IDispatch接口
在您的示例中:
Dim strictUpCast As Class1
Set strictUpCast = downCast
Dim objectUpCast As Object
Set objectUpCast = downCast
第二行调用QueryInterface,询问Class1接口,如预期的那样
在您的另一个示例中:
Dim strictUpCast As Class1
Set strictUpCast = downCast
Dim objectUpCast As Object
Set objectUpCast = downCast
在第二行,可能会发生2件事:
Dim objectUpCast As Object
Set objectUpCast = iUnk
其中,在第二行,VB调用QueryInterface并请求IDispatch接口,因为变量(右侧)指向一个自定义接口(IUnknown本身不是从IDispatch派生的)。IDispatch接口知道默认接口,这就是返回的是的,就这样!我想知道,你能解释一下这是怎么回事吗?据我所知,VBA中定义的每个接口/类都扩展了IUnknown,因此可以将其转换为IUnknown。但为什么对IUnknown的强制转换然后对对象的强制转换会跳转到默认接口。如果一个接口已经扩展了IUnknown,那么将该接口强制转换到IUnknown不是一个有效的禁止操作吗?(很明显这是可行的,但我很想知道原因:)@Greedo我已经编辑了答案,包括一个解释