我确信这是重复的,但我找不到答案。
System.Linq.Queryable
有一个带有以下签名的方法:
public static int Count<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate);
如何使用System.Type::GetMethod
方法获取此方法?
typeof(System.Linq.Queryable).GetMethod("Count", type[]{ ??? });
答案 0 :(得分:1)
您可以使用
var method = typeof (System.Linq.Queryable).GetMethods().Single(a=>a.Name == "Count" && a.GetParameters().Length == 2);
之后,如果你想调用它
method.MakeGenericMethod(typeof (YourType));
另外,它可以被过滤(用于不同的选择):
var sel1 = typeof (Queryable).GetMethods().Single(a => a.Name == "Select"
&& a.MakeGenericMethod(typeof(object), typeof(object)).GetParameters()[1].ParameterType == typeof(Expression<Func<object, object>>));
var sel2 = typeof(Queryable).GetMethods().Single(a => a.Name == "Select"
&& a.MakeGenericMethod(typeof(object), typeof(object)).GetParameters()[1].ParameterType == typeof(Expression<Func<object,int, object>>));
答案 1 :(得分:1)
尝试最少的方法可能是使用表达式树捕获所需的方法,然后深入研究以查找方法引用。您可以执行此操作一次以获取通用方法定义,然后缓存结果并根据需要重复使用它。
Expression<Func<IQueryable<int>, int>> getCount = p => p.Count();
MethodInfo countMethod = ((MethodCallExpression)getCount.Body).Method.GetGenericMethodDefinition();
这有利于稍微对API更改具有弹性(例如,添加更多“Count”成员);返回的方法将是您的表达式在编译时绑定的任何方法。
如果您愿意,可以将此行为提取到实用程序方法中:
public static MethodInfo MethodOf(Expression<Action> accessExpression, bool dropTypeArguments = false)
{
if (accessExpression == null)
throw new ArgumentNullException("accessExpression");
var callExpression = accessExpression.Body as MethodCallExpression;
if (callExpression == null)
throw new ArgumentException("Expression body must be a method call.", "accessExpression");
var method = callExpression.Method;
if (dropTypeArguments && method.IsGenericMethod)
return method.GetGenericMethodDefinition();
return method;
}
public static MethodInfo MethodOf<TInstance>(Expression<Action<TInstance>> call, bool dropTypeArguments = false)
{
if (call == null)
throw new ArgumentNullException("call");
var callExpression = call.Body as MethodCallExpression;
if (callExpression == null)
throw new ArgumentException("Expression body must be a method call.", "call");
var method = callExpression.Method;
if (dropTypeArguments && method.IsGenericMethod)
return method.GetGenericMethodDefinition();
return method;
}
对静态样式调用使用第一个重载,对实例样式调用使用后者,例如:
var countMethod1 = Extensions.MethodOf(() => Queryable.Count(default(IQueryable<int>)), dropTypeArguments: true);
var countMethod2 = Extensions.MethodOf((IQueryable<int> p) => p.Count(), dropTypeArguments: true);
要保留类型参数(例如,要解析Count<int>()
而不是Count<T>()
),只需省略dropTypeArguments: true
参数或将其设置为false
。
请注意,这些并不十分全面;例如,他们不会在声明类型上删除泛型参数(仅限于方法本身)。随意使用,延长或扔掉:)。