反思:如何获得通用方法?

sl3*_*dg3 29 c# reflection

可能重复:
如何使用反射来调用泛型方法?
选择具有反射的右通用方法

嗨,您好

假设我在类中有以下两种方法:

public void MyMethod(object val) {}
public void MyMethod<T>(T val) {}
Run Code Online (Sandbox Code Playgroud)

通过反射,我可以得到第一个这样的方法:

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

但是我如何获得第二种通用​​方法呢?

Luk*_*keH 49

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();
Run Code Online (Sandbox Code Playgroud)

  • thx - 没想到会那么复杂:-) (5认同)
  • 哇,这太令人讨厌了 (5认同)

Ani*_*Ani 8

我会这样做:

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();
Run Code Online (Sandbox Code Playgroud)

我们正在寻找一种名为"MyMethod"的方法,它是一种通用方法,只有一个没有约束的类型参数,以及一个与type-parameter类型相同的"normal"参数.

显然,如果你不是非常精确,你可以做到最低限度消除歧义,例如:

var myMethod = typeof(MyClass)
              .GetMethods()
              .Single(m => m.Name == "MyMethod" && m.IsGenericMethodDefinition);
Run Code Online (Sandbox Code Playgroud)