如何获取泛型扩展方法的MethodInfo?

11

我有一个 IEnumerable<T>,我想通过反射调用 Enumerable.Contains 方法。我只是在努力弄清楚语法。这是我目前的代码:

var containsMethod = typeof(Enumerable).GetMethod("Contains", 
  new[] {
    typeof(IEnumerable<T>), 
    typeof(T) 
  });

这只会返回一个 null。

获取 MethodInfo 的正确方式是什么?


可能是使用反射选择正确的泛型方法的重复问题。 - nawfal
1个回答

19

如何正确获取MethodInfo?

您需要找到适当的参数并构造出通用方法,但这有点麻烦。在这种情况下,您知道只有两个Contains重载,而您想要的那个重载有两个参数,因此可以使用:

var method = typeof(Enumerable).GetMethods()
                               .Where(m => m.Name == "Contains")
                               .Single(m => m.GetParameters().Length == 2)
                               .MakeGenericMethod(typeof(T));

您应该能够适当地调用它。

1
这是一个很好的代码,只适用于这个方法和这个类。一般来说,必须有越来越多的检查。 - Viktor Lova
你可能想将 Where 中的检查折叠到 Single 中,即 m => m.Name == "Contains" && m.GetParameters().Length == 2 - Sergey Kalinichenko
@dasblinkenlight:我个人认为这种形式更易读。当然,你可以将检查折叠在其中。但这更接近于我的思考方式——找到所有包含方法,然后找到具有正确参数数量的方法。 - Jon Skeet
@nsinreal:是的,总的来说,找到通用方法确实很麻烦。 - Jon Skeet
@JonSkeet: 嗯,我理解可以有一种优美的语法来选择通用方法。类似于 GetMethods(types: (Type T) => new Type[] { typeof(IEnumerable<>).WithGenericTypes(T), T }) - 通过表达式。你认为这样的语法真的有必要吗?它可以更好地编写吗? - Viktor Lova
@nsinreal:我认为这种情况很少发生,所以使用我提供的代码应该不会太糟糕。 - Jon Skeet

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