使用反射与COM互操作

3

在Interop调用之后,我会得到一个COM对象。我知道这个对象将是三个可能的COM类(Class1、Class2、Class3)中的一个,但在运行时不知道它是哪一个。

对该对象进行反射 (interopObject.GetType()),返回System.__ComObject的基本RCW包装器。

我需要的是在对象上设置一些属性 - Text1、Text2、... Text30(实际名称),这些属性存在于所有三个类中。

因此,问题是,我是否可以以某种方式获取对象的运行时类型(这将解决我的问题,但可能不可能,因为.NET运行时可能没有该信息),或者可以盲目地设置COM对象的属性。

这是我的当前代码,它失败了:

for ( int i = 1; i <= 30; i++ )
{
  ProprertyInfo pi =interopObject.GetType().GetProperty("Text" +i.ToString()) 
  // this returns null for pi
  pi.GetSetMethod().Invoke(interopObject, new object[] { someValue });
}

感谢Marc,这三个技巧将被永久收藏在我的套路库中:

private static object LateGetValue(object obj, string propertyName)
{
  return RuntimeHelpers.GetObjectValue(NewLateBinding.LateGet(obj, null,
            propertyName, new object[0], null, null, null));
}

private static void LateSetValue(object obj, string propertyName, object value)
{
  NewLateBinding.LateSet(obj, null, propertyName, new []{value}, null, null);
}

private static void LateCallMethod(object obj, string methodName)
{
  NewLateBinding.LateCall(obj, null, methodName, new object[0], null,
            null, null, true);
}
1个回答

8
在C# 4.0中,dynamic类型是实现鸭子类型的理想选择。
在此之前,我想知道是否使用VB.Net更好一些,可以使用Option Strict Off进行后期绑定。
最坏情况:用VB.Net编写代码,然后使用反射器为您编写C#代码;-p 以下是一个示例,需要引用Microsoft.VisualBasic.dll,在C#中也是可以的:
public static object GetValue(object obj, string propertyName)
{
    return RuntimeHelpers.GetObjectValue(NewLateBinding.LateGet(obj, null,
         propertyName, new object[0], null, null, null));
}

不幸的是,代码截止日期是明天,而不是在秋季/冬季的某个时候 :) 另外,VB 不是一个选项。 是的,我确实需要一种语言中的鸭子类型,而该语言目前还不支持它... - SWeko
就像我说的一样,使用反射器获取C#,然后...我会尝试做一个例子...(2秒钟) - Marc Gravell
尝试了NewLateBinding.LateGet的神奇功能,现在似乎可以使用。 我很高兴。 - SWeko
1
我又查了一下,我喜欢NewLateBinding类的动态性。向Marc致敬。 - SWeko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接