Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
987 views
in Technique[技术] by (71.8m points)

c# - Using Reflection with COM Interop

After an interop call, I get back a COM object. I know this object will be one of three possible COM classes (Class1, Class2, Class3), but do not know which one in runtime.

The reflection upon that object (interopObject.GetType()) returns the base RCW wrapper of System.__ComObject.

What I need is to set some properties on the object - Text1, Text2, ... Text30 (actual names, btw :)), which exist in all three classes.

So, the question is, can I somehow get the runtime type of the object (this would solve my problem, but might be impossible, as the .net runtime might not have that info), or can I set a property of a COM object blindly

this is my current code, which fails:

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 });
}

Thanks to Marc, these three go in my permanent gimmicks collection:

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);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In C# 4.0, dynamic would be ideal for this type of duck-typing.

Until then, I wonder if VB.Net would be better, with Option Strict Off to allow late binding against object.

Worst case: write it in VB.Net, then use reflector to write the C# for you ;-p

Here's an example, that requires a reference to Microsoft.VisualBasic.dll, but is fine in C#:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...