有你在真好 的个人博客
C#如何获取动态类型的实际数据类型?如何判断Com+的类型
阅读:2042 添加日期:3/30/2021 5:40:44 PM

一、普通变量

在C#中,通常,我们要得到一个变量类型,使用GetType()方法。比如:

int m = 0;
Type type = m.GetType();
C#如何获取动态类型的实际数据类型?如何判断Com+的类型

是不是感觉很简单。

二、如何判断动态类型的实际数据类型?

动态类型的关键字是dynamic,怎么取它的类型呢?

通过GetType()也一样可以得到的。比如:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

如上图,我们通过GetType()方法,还是可以取到动态类型dynamic的实际数据类型的

三、如何获取Com+的变量数据类型?

有了前面2个例子,你是不是想当然的以为判断Com+的变量类型觉得也很简单呢?

错,下面我们一起来看看,为什么上面的方法失灵了。

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

如上图,我们声明一个Com+变量,然后获取它的Document属性,通过智能感知,看到window.Document显示为dynamic动态类型。

下面我们用GetType()方法,来获取这个Com+的动态变量的实际类型是啥,程序跑起来:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

跑起来后,你会看到,类型是System.__ComObject,这是它的类型吗?嗯,也算是,但是这个类型是没有用的,因为你无法转换。

事实上,所有的Com+动态变量,都显示为System.__ComObject类型,而这个类型是无法使用的。

四、如何取到Com+的实际类型?

要想实际取得Com+的数据类型,通过上面的常规方法是行不通的。得用
Microsoft.VisualBasic.Information.TypeName()方法。

该方法需要引入Microsoft.VisualBasic.dll,如下图:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

下面我们再来跑一下代码:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

此时,我们就得到了它真正的实际数据类型了:IShellFolderViewDual3。

五、Com+的变量异常

Com+是一个很特殊的东西,如上面,即便您看到了实际类型是IShellFolderViewDual3,有的时候,你也无法强制转换,比如IShellDispatch6这个类型,在强制转换时时,将引发以下异常:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

System.InvalidCastException
  HResult=0x80004002
  Message=无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“Shell32.IShellDispatch6”。此操作失败的原因是对 IID 为“{286E6F1B-7113-4355-9562-96B7E9D64C54}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 不支持此接口 (异常来自 HRESULT:0x80004002 (E_NOINTERFACE))。
  Source=<无法计算异常源>
  StackTrace:
<无法计算异常堆栈跟踪>
C#如何获取动态类型的实际数据类型?如何判断Com+的类型

那么这种异常,要怎么解决呢?以IShellDispatch6为例,我们看一下它的继承,如下图:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

我们会看到它实际是继承了IShellDispatch5这个接口类,我们只需要把强制转换,改为IShellDispatch5即可,代码如下:

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

C#如何获取动态类型的实际数据类型?如何判断Com+的类型

这样,您再编译运行的话,就可以通过了。


祝您用餐愉快。