对于类型正确的对象,无效的强制转换异常是什么?

时间:2015-07-20 14:02:35

标签: .net exception casting com office-interop

请帮助我了解这里发生的事情。

这是我的代码:

Dim DocProps As Microsoft.Office.Core.DocumentProperties
Dim WeekName As String = StartDate.ToString("yyMMdd") & "_" & EndDate.ToString("yyMMdd")
Dim PropName As String = "Log Week"
DocProps = WeeklyReports.CustomDocumentProperties

我在最后一行收到了一个无效的强制转换异常:

  

"无法转换类型为' System .__ ComObject'的COM对象。接口   键入' Microsoft.Office.Core.DocumentProperties'。此操作失败   因为QueryInterface调用COM组件的接口   与IID' {2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}'由于失败而失败   以下错误:不支持此类接口(来自HRESULT的异常:   0x80004002(E_NOINTERFACE))。"

文档说:

我试图访问工作簿的CustomDocumentProperties成员,以便检查属性的值。

文档说:

  

返回或设置代表所有的DocumentProperties集合   指定工作簿的自定义文档属性。

为什么我感到困惑:

此对象似乎有变色龙类型。以下是我尝试追踪它的原因:

Dim DocProps As Object
DocProps = WeeklyReports.CustomDocumentProperties
Debug.Print(DocProps Is Nothing)
Debug.Print(TypeName(DocProps))
Debug.Print(TypeOf(DocProps) is DocumentProperties)
Debug.Print(GetType(DocumentProperties).AssemblyQualifiedName)
Debug.Print(DocProps.GetType.ToString)    
Debug.Print(vbNewLine)

For Each InterfaceType As Type In GetType(DocumentProperties).GetInterfaces
        Debug.Print(InterfaceType.ToString)
    Next

DirectCast(DocProps, Microsoft.Office.Core.DocumentProperties)
DocProps.Add(Name:=PropName,
             LinkToContent:=False,
             Type:=MsoDocProperties.msoPropertyTypeString,
             Value:=WeekName)

我在输出窗口中得到以下结果。

  


  DocumentProperties
  假
  Microsoft.Office.Core.DocumentProperties,Office,Version = 14.0.0.0,Culture = neutral,PublicKeyToken = 71e9bce111e9429c
  System .__ ComObject

     

System.Collections.IEnumerable

因此,我们可以看到有关此对象类型的信息似乎存在一些冲突。

TypeName()函数返回" DocumentProperties",而.GetType只是将其视为COM对象,而我无法告诉TypeOf()看到的内容,它当然不会将其视为与Microsoft.Office.Core.DocumentProperties的匹配。

接下来,我们看到这个疯狂对象实现了什么接口,并且向我们揭示的唯一一个是IEnumerable接口。

因此,我们到达下一行,我尝试使用DirectCast,并获得与原始代码相同的InvalidCast Exception。所以看来我们可以信任这个GetInterfaces方法,因为很明显这个对象没有实现DocumentProperties接口,或者我们能够将它作为这样的类型转换,对吧?右????

嗯......也许是因为在上一次测试中,我发现了另一个异常,进一步混淆了这个对象的真实类型;如果我跳过DirectCast尝试并直接转到对象的.Add方法而不将其作为任何类型转换,它就会成功。现在,IEnumerable接口没有.Add方法 - 所以它来自哪里呢?就此而言,TypeName来自哪里,如果它不属于DocumentProperties类型,因为所有其他测试似乎都表示???

那又是什么?

整个项目中只有一个命名空间带有" DocumentsProperties"成员 - 为了清晰起见,我只是输入了完全限定的名称,而不是必需的。根据文档,这是对象的正确名称空间。 (见上面的链接)

当我尝试弱打字时,我得到的东西似乎与这个对象的类型相矛盾。当我跳过DirectCast行时,我能够成功执行此对象的.Add方法。我可以使用为DocumentProperties接口定义的参数名称调用此方法的事实,加上TypeName结果似乎表明我有一个对象输入为此接口,但TypeOf比较和DirectCast以及隐式转换异常表明我没有。

我的对象看起来像鸭子,像鸭子一样嘎嘎叫,为什么它拒绝被当作鸭子?

0 个答案:

没有答案