views:

141

answers:

1

Hi,

I feel like I'm so close to working this out and have read dozens of articles and existing questions.

I have a method like this:

public T DoStuff(object arg1, object arg2)
{
  /* Do stuff and return a T */
}

And I need to be able to pass this method to another class for callback purposes.
However, when this other class calls back it will do so with a different expected return type that is only known at runtime.

E.g.:

public void SomeMethod(MethodInfo m, ref object caller)
{
  MethodInfo callback = m.MakeGenericMethod(new Type[] { runtimeType });
  callback.Invoke(caller, new [] { arg1val, arg2val });
}

/* DoStuff() will make a call to SomeMethod() passing 
 * itself (the method and the object) */

However, instead of this I would like to be able to

  1. Pass only a single callback object (i.e. a delegate or Func<>) to SomeMethod.
  2. Be able to modify this object appropriately for the generic call.
  3. Have type-safe parameters for the call as I would with a delegate/Func<>.

I've found approaches that suit each of these individually but none that covers all of them.

Is it possible?

+4  A: 

From the MakeGenericMethod usage, I assume that the method (in your example) is generic in T:

public T DoStuff<T>(object arg1, object arg2)

Given the amount of reflection you are doing, this simply isn't doing you any favors; for use from reflection you might as well use:

public object DoStuff(Type type, object arg1, object arg2)

And use (for example) Activator.CreateInstance(type) to create an instance. The above can now be used with a delegate; for example a Func<Type,object,object,object>.

Marc Gravell
Yeah you're right and good points. I feel dirty using this much reflection but I can't see another way of doing runtime parsing of data into arbitrary code objects. For a moment I was concerned about calling other generic methods as I wouldn't have an actual "T" type to work with but seeing as I'm calling them through reflection too this isn't a big issue and they can probably even be rewritten in a similar way to this. Thanks!
Graphain