i am currently working on an AddIn for Inventor(3d Modeling Software). When you are using the api there are two different kind of documents
the api provides me a method which returns the selected document.
PartDocument part = ((PartDocument)application.ActiveDocument);
during runtime this cast works. The compiler tells me that this is a suspicious cast, because the 'PartDocument' does not implements the type the 'application.ActiveDocument' returns.
[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
{
}
So why is this working ? Can someone explain this this to me ?
And how can i test this ?
var documentMock =new Mock<PartDocument>();
var applicationMock = new Mock<Application>();
applicationMock.Setup(x => x.ActiveDocument).Returns(documentMock.Object);
The compiler tells me that he cannot cast from 'PartDocument' to '_Document' --> this is true, so why is it working during runtime ?
Thanks in advance
It works because it is a COM type. For COM type casting, the interop handler will automatically call IUnknown.QueryInterface
on the COM object (every COM object implements IUnknown) to find out if it supports PartDocument
interface, and get the location of the relevant VTable. This is entirely disconnected from the .NET type specification, and, theoretically, could return a different result each time it was called.