I'm working with a COM-API, Autodesk Inventor.
This test passes:
[Test]
public void CastTest()
{
Inventor.Document document = _application.ActiveDocument;
var assemblyDocument = (Inventor.AssemblyDocument)document;
Assert.NotNull(assemblyDocument);
}
This test fails:
[Test]
public void IsAssignableFromTest()
{
Assert.IsTrue(typeof(Inventor.Document).IsAssignableFrom(typeof(Inventor.AssemblyDocument)));
}
I don't know much about COM at all, is there a way to check if one COM type "inherits" another using reflection or some COM voodoo?
The COM type system is not compatible to .NET. Instead you are programming against wrappers (so called RCW's). To test if you can convert one COM object into another one, COM provides the
QueryInterface
-method as a member ofIUnknown
, which every COM object must implement. However .NET hides those details for you so that you can write COM code that does "feel" like .NET code.If you take a look at the disassembly of Inventors interop-library, you will recognize, that there is no direct relation between
Document
andAssemblyDocument
. Both are interfaces that do only implement the default interface of their respective coclasses and are attributed with theCoClassAttribute
. But in their inheritance tree, they are not directly related to each other. They may both implement the same interface (I guess something likeIDocument
), but you cannot convert a WinForms button into a picture box either, even though they both implment theControl
-interface.This is what reflection and
IsAssignableFrom
is testing: The metadata that each CLR-type provides. COM works different here. Each COM object can "decide" on it's own if it can be called from another interface. Therefor it implementsQueryInterface
. And therefor you have to create an instance of your source type, before you can perform your test (COM does not know static members).A traditional cast does call
QueryInterface
, so your test could simply look like:Otherwise you could call
QueryInterface
directly through theMarshal
-class.However, it is not possible to test type metadata through reflection with COM objects.
If you want to use the Inventor API, you could check for document type before casting it to another type.
Ex.: (VBA)
Best regards,