反射:如何获取一个通用方法?

34

可能的重复:
如何使用反射调用通用方法?
使用反射选择正确的通用方法

你好

假设我有一个类中的以下两个方法:

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

通过反射,我可以像这样获取第一个方法:

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

但是我该如何获取第二个通用方法?

可能是重复的问题:https://dev59.com/nXA65IYBdhLWcg3wyR2k - Sasha Goldshtein
1
@AakashM:这不是那个特定问题的副本。 - LukeH
如果这些解决方案在代码方面很烦人,一个好的解决方法是在您自己的代码中拥有一个私有的通用方法来调用您想要定位的通用方法,然后使用反射调用它,在这种情况下,您可以轻松解决此问题:https://dev59.com/Z3VC5IYBdhLWcg3woCrN#232621 - Philippe
2个回答

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

6
谢谢 - 没想到会这么复杂 :-) - sl3dg3
5
哇,那真是极其恼人。 - Eric Rini

9
我会这样做:
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();

我们正在寻找一种名为“MyMethod”的方法,它是一个通用方法,具有一个类型参数且没有约束条件,并且有一个与类型参数相同类型的“普通”参数。
显然,如果您不需要非常精确,您可以只做最少的歧义消除,比如:
var myMethod = typeof(MyClass)
              .GetMethods()
              .Single(m => m.Name == "MyMethod" && m.IsGenericMethodDefinition);

谢谢 - 第二个查询是一个很好的解决方法。但在我的情况下,我更喜欢保持精确,因为有更多的重载方法... - sl3dg3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接