IsAssignableFrom with COM [英] IsAssignableFrom with COM
问题描述
我正在使用COM-API,Autodesk Inventor。
I'm working with a COM-API, Autodesk Inventor.
此测试通过:
[Test]
public void CastTest()
{
Inventor.Document document = _application.ActiveDocument;
var assemblyDocument = (Inventor.AssemblyDocument)document;
Assert.NotNull(assemblyDocument);
}
此测试失败:
[Test]
public void IsAssignableFromTest()
{
Assert.IsTrue(typeof(Inventor.Document).IsAssignableFrom(typeof(Inventor.AssemblyDocument)));
}
我完全不了解COM,检查一个COM类型是否继承另一个使用反射或一些COM voodoo?
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?
推荐答案
COM类型系统不兼容。净。相反,你是编程的包装(所谓的RCW的)。要测试是否可以将一个COM对象转换为另一个COM对象,COM提供 QueryInterface
- 方法作为 IUnknown
的成员,每个COM对象必须实现。但是.NET隐藏了这些细节,所以你可以编写感觉像.NET代码的COM代码。
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 of IUnknown
, 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.
如果你看一看Inventor的反汇编您将认识到文档
和 AssemblyDocument
之间没有直接关系。两者都是只实现其各自coclass的默认接口的接口,并且归属于 CoClassAttribute
。但在它们的继承树中,它们并不直接相互关联。他们可以实现相同的接口(我想像 IDocument
),但你不能将WinForms按钮转换成图片框,即使他们都暗示 Control
-interface。
If you take a look at the disassembly of Inventors interop-library, you will recognize, that there is no direct relation between Document
and AssemblyDocument
. Both are interfaces that do only implement the default interface of their respective coclasses and are attributed with the CoClassAttribute
. But in their inheritance tree, they are not directly related to each other. They may both implement the same interface (I guess something like IDocument
), but you cannot convert a WinForms button into a picture box either, even though they both implment the Control
-interface.
这是什么反射和 IsAssignableFrom
:每个CLR类型提供的元数据。 COM在这里不同。每个COM对象可以自己决定,如果它可以从另一个接口调用。因此它实现 QueryInterface
。因此,你必须创建一个源类型的实例,然后才能执行你的测试(COM不知道静态成员)。
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 implements QueryInterface
. And therefor you have to create an instance of your source type, before you can perform your test (COM does not know static members).
一个传统的转换调用 QueryInterface
,所以你的测试可以看起来像这样:
A traditional cast does call QueryInterface
, so your test could simply look like:
[Test]
public void IsAssignableFromTest()
{
Assert.IsNotNull(_application.ActiveDocument as Inventor.AssemblyDocument);
}
否则您可以调用 QueryInterface
直接通过 Marshal
-class。
Otherwise you could call QueryInterface
directly through the Marshal
-class.
但是,不可能通过反射测试类型元数据与COM对象。
However, it is not possible to test type metadata through reflection with COM objects.
这篇关于IsAssignableFrom with COM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!