33

Possible Duplicates:
How to use reflection to call generic Method?
Select Right Generic Method with Reflection

Hi there

Let's say I have two following two methods in a class:

public void MyMethod(object val) {}
public void MyMethod<T>(T val) {}

With reflection, I could get the first Method like this:

Type[] typeArray = new Type[1];
typeArray.SetValue(typeof(object), 1);
var myMethod = myInstance.GetType().GetMethod("MyMethod", typeArray);

But how can I get the second, generic method?

Community
  • 1
  • 1
sl3dg3
  • 5,026
  • 12
  • 50
  • 74
  • Possible duplicate of: http://stackoverflow.com/questions/3631547/select-right-generic-method-with-reflection – Sasha Goldshtein Mar 07 '11 at 10:19
  • 1
    @AakashM: This *is not* a duplicate of that particular question. – LukeH Mar 07 '11 at 10:28
  • If the solutions to this are annoying in terms of code, a good workaround is to have a private generic method in your own code that calls the generic method you want to target, then call it using reflection in which case you can get away with this: https://stackoverflow.com/a/232621/920 – Philippe Jul 05 '19 at 07:31

2 Answers2

52
var myMethod = myInstance.GetType()
                         .GetMethods()
                         .Where(m => m.Name == "MyMethod")
                         .Select(m => new {
                                              Method = m,
                                              Params = m.GetParameters(),
                                              Args = m.GetGenericArguments()
                                          })
                         .Where(x => x.Params.Length == 1
                                     && x.Args.Length == 1
                                     && x.Params[0].ParameterType == x.Args[0])
                         .Select(x => x.Method)
                         .First();
LukeH
  • 263,068
  • 57
  • 365
  • 409
9

I would do it like this:

var methods = from m in typeof(MyClass).GetMethods()
              where m.Name == "MyMethod"
                 && m.IsGenericMethodDefinition

              let typeParams = m.GetGenericArguments()
              let normalParams = m.GetParameters()

              where typeParams.Length == 1 && normalParams.Length == 1
                 && typeParams.Single() == normalParams.Single().ParameterType
                 && !typeParams.Single().GetGenericParameterConstraints().Any()

              select m;

var myMethod = methods.Single();

We're looking for a method called "MyMethod" that is a generic method with a single type-parameter having no constraints, and one 'normal' parameter of the same type as the type-parameter.

Obviously, if you're not looking to be very precise, you can just do the bare minimum to disambiguate, such as:

var myMethod = typeof(MyClass)
              .GetMethods()
              .Single(m => m.Name == "MyMethod" && m.IsGenericMethodDefinition);
Ani
  • 111,048
  • 26
  • 262
  • 307
  • thx - the second query is a nice workaround. But in may case I rather stay precise since there are more overloaded methods... – sl3dg3 Mar 07 '11 at 10:58