SWeko
SWeko

Reputation: 30882

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

Upvotes: 3

Views: 3915

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062745

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

Upvotes: 8

Related Questions