在静态类上查找泛型方法

时间:2016-05-12 13:36:38

标签: c# generics reflection

我有一个班级

public static class MyClass
{

    public static T MyMethod<T>(T item) where T : ISomeInterface<T>, new
    {
        return MyMethod(new[] { item}).First();
    }

    public static IEnumerable<T> MyMethod<T>(params T[] items) where T : ISomeInterface<T>, new
    {
         // for simplicity
         return items.ToList();
    }
}

和一堆甚至更复杂的重载。 现在我想用

来扩展类(因为我想从powershell调用)
    public static IEnumerable MyMethod(string typeName, params object[] items)
    {
        var type = Type.GetType(typeName, true, true);
        var paramTypes = new Type[] { type.MakeArrayType() };
        var method = typeof(MyClass).GetMethod(
            "MyMethod", BindingFlags.Public | BindingFlags.Static
                | BindingFlags.IgnoreCase, null, paramTypes, null);
        return method.Invoke(null, new object[] { items });
    }

method始终为空。通过GetMethod()获取特定方法的正确方法是什么。

1 个答案:

答案 0 :(得分:2)

我认为您不能使用GetMethod来搜索通用方法(我不确定)。但是,您可以使用GetMethods获取所有方法,然后像这样过滤它们:

var method = typeof (MyClass)
    .GetMethods(
        BindingFlags.Public | BindingFlags.Static )
    .Single(x => x.Name == "MyMethod"
        && x.IsGenericMethod
        && x.ReturnType == typeof(IEnumerable<>)
                          .MakeGenericType(x.GetGenericArguments()[0]));

请注意,最后一个条件是检查方法的返回类型是IEnumerable<T>,这样我们就不会得到返回T的方法。

请注意,您可以将method变量缓存为静态变量,这样您就不必每次都搜索它。

请注意,返回的方法仍处于打开状态(仍为MyMethod<T>)。您仍然需要通过调用MakeGenericMethod方法创建一个封闭版本,如下所示:

var closed_method = method.MakeGenericMethod(type);

然后你可以像这样调用它:

return (IEnumerable)closed_method.Invoke(null, new object[] { items });