反思COM互操作对象 [英] Reflection on COM Interop objects
问题描述
试图创建一个映射器为微软Office对象到POCO的,发现这个
Trying to create a mapper for an Microsoft Office object to POCO's and found this
// doesn't work
// returns an empty array where o is a RCW on an office object
foreach(var pi in o.GetType().GetProperties() )
tgt.SetValue(rc, pi.GetValue(o, null));
因此不得不求助于此
so have to resort to this
foreach(var field in tgt.GetFields() ){
var pv = o.InvokeMember(field.Name, System.Reflection.BindingFlags.GetProperty, null, o, null);
i.SetValue(rc, pv);
}
这适用于现在,但不知道为什么 RCW.GetProperties()
不在这里工作了?
推荐答案
另外两个答案写这篇文章是正确的,但他们错过来解释如何COM对象的后期绑定看起来条款的重要机会。 NET类型系统。 当你调用的GetType
COM对象上,则返回值是 __ ComObject
内部类型,而不是COM您通常写互操作code时,与工作接口类型。的你可以看到在调试器,或用一些code像 Console.WriteLine(o.GetType() .Name点);
The other two answers as of this writing are correct, but they miss an important opportunity to explain how the late binding of a COM object looks in terms of the .NET type system. When you call GetType
on the COM object, the return value is the __ComObject
internal type, not the COM interface type that you normally work with when writing interop code. You can see this in the debugger, or with some code like Console.WriteLine(o.GetType().Name);
.
在 __ ComObject
类型没有属性;这就是为什么你会得到一个空数组当你调用 o.GetType()。GetProperties中()
。 (至少有些东西在生活中有意义!)
The __ComObject
type has no properties; that's why you get an empty array when you call o.GetType().GetProperties()
. (At least some things in life make sense!)
如果你反编译 InvokeMember
方法,你会发现它有特殊处理的COM对象,委托调用一个内部本地方法。对于常规.NET对象,该方法使用常规。NET反射,获取相应的的MemberInfo
的请求的成员,并调用它。
If you decompile the InvokeMember
method, you'll find that it has special handling for COM objects, delegating the call to an internal native method. For "regular" .NET objects, the method uses "regular" .NET reflection, retrieving the appropriate MemberInfo
for the requested member, and invoking it.
您的可以的上的接口的类型使用.NET反射。例如,如果您知道对象是Excel 工作表
,您可以使用的typeof(表).GetProperties()
,并使用所产生的的PropertyInfo
情况下,你的对象。如果您不知道对象在编译时的类型,但是,您需要调用的GetType()
,因为在你的榜样code。在这种情况下,你坚持使用 InvokeMember
。
You can use .NET reflection on the interface type. For example, if you know that the object is an Excel Worksheet
, you can use typeof(Worksheet).GetProperties()
, and use the resulting PropertyInfo
instances with your object. If you don't know the type of the object at compile time, however, you need to call GetType()
, as in your example code. In that case, you're stuck with using InvokeMember
.
这篇关于反思COM互操作对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!