可疑的演员阵容中没有继承自的解决方案中的类型->为啥/以某种方式起作用

Posted

技术标签:

【中文标题】可疑的演员阵容中没有继承自的解决方案中的类型->为啥/以某种方式起作用【英文标题】:suspicious cast there is no type in the solution which is inherited from--> why/somehow it is working可疑的演员阵容中没有继承自的解决方案中的类型->为什么/以某种方式起作用 【发布时间】:2021-04-15 21:42:16 【问题描述】:

我目前正在为 Inventor(3d 建模软件)开发插件。当您使用 api 时,有两种不同类型的文档

组装文件 部分文档

api 为我提供了一个返回所选文档的方法。

   PartDocument part = ((PartDocument)application.ActiveDocument);

在运行时,此演员表有效。编译器告诉我这是一个可疑的转换,因为“PartDocument”没有实现“application.ActiveDocument”返回的类型。

 [TypeLibType(TypeLibTypeFlags.FDispatchable)]
  [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  [Guid("xxxxxx")]
  [DefaultMember("Type")]
  [ComImport]
  public interface PartDocument
  
....
 [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  [TypeLibType(TypeLibTypeFlags.FDispatchable)]
  [Guid("xxxxx")]
  [DefaultMember("Type")]
  [ComImport]
  public interface Application
  ...

    [DispId(50331905)]
    _Document ActiveDocument  [DispId(50331905), MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] get; 
[Guid("xxxxxx")]
  [CoClass(typeof (_DocumentClass))]
  [ComImport]
  public interface _Document : Document, _VbaImplementationEvents_Event
  
  

那么为什么这有效?有人可以向我解释一下吗?

我该如何测试呢?

var documentMock =new Mock<PartDocument>();
var applicationMock = new Mock<Application>();
applicationMock.Setup(x => x.ActiveDocument).Returns(documentMock.Object);

编译器告诉我他不能从 'PartDocument' 转换为 '_Document' --> 这是真的,为什么它在运行时工作?

提前致谢

【问题讨论】:

【参考方案1】:

它之所以有效,是因为它是一种 COM 类型。对于COM类型转换,interop handler会自动调用COM对象上的IUnknown.QueryInterface(每个COM对象都实现了IUnknown)来判断它是否支持PartDocument接口,并获取相关VTable的位置。这与 .NET 类型规范完全脱节,理论上,每次调用时都可能返回不同的结果。

【讨论】:

以上是关于可疑的演员阵容中没有继承自的解决方案中的类型->为啥/以某种方式起作用的主要内容,如果未能解决你的问题,请参考以下文章

转换为多重继承

非 Diamond 类型中的虚拟继承

有没有办法修改子类,以便所有超类继承更改?

Libgdx 之Actor 演员类

Laravel 基于自的多态关系

怎么还原sql2008数据库 heroes可疑