如何获取Expression.Lambda<TDelegate>(Expression, ParameterExpression[])的MethodInfo?
获取Expression.Lambda(Expression, ParameterExpression[])的MethodInfo
你遇到的AmbiguousMatchException是因为Expression.Lambda存在多个重载(包括泛型和非泛型版本),直接用GetMethod匹配参数类型时无法区分歧义。以下是几种更简洁可靠的解决方案:
方法一:精准筛选泛型方法定义
直接筛选名为Lambda的公共静态泛型方法,匹配参数数量和类型:
MethodInfo lambdaMethod = typeof(Expression) .GetMethods(BindingFlags.Public | BindingFlags.Static) .Where(m => m.Name == nameof(Expression.Lambda) && m.IsGenericMethodDefinition) .Single(m => m.GetParameters().Length == 2 && m.GetParameters()[0].ParameterType == typeof(Expression) && m.GetParameters()[1].ParameterType == typeof(ParameterExpression[]) );
这种方式去掉了原代码中多余的ReturnParameter.Member强制转换,直接通过方法本身获取参数,避免不必要的类型转换风险。
方法二:利用表达式树推导(最安全)
通过创建表达式树,让编译器帮我们定位到目标重载,再提取泛型方法定义:
// 这里用Func<int>作为示例TDelegate,可替换为任意委托类型 Expression<Func<Expression, ParameterExpression[], Expression<Func<int>>>> expr = (body, parameters) => Expression.Lambda<Func<int>>(body, parameters); MethodInfo lambdaMethod = ((MethodCallExpression)expr.Body).Method.GetGenericMethodDefinition();
这种方式完全依赖编译器的类型检查,不会出现匹配错误,是最可靠的方案。
方法三:先构造具体泛型方法再获取定义
如果明确知道要使用的委托类型,可以先构造一个具体的泛型方法实例,再获取其泛型定义:
MethodInfo lambdaMethod = typeof(Expression) .GetMethod(nameof(Expression.Lambda), new[] { typeof(Expression), typeof(ParameterExpression[]) }) ?.MakeGenericMethod(typeof(Func<int>)) .GetGenericMethodDefinition();
注意:如果GetMethod仍返回null(说明参数匹配还是有歧义),优先使用前两种方法。
内容的提问来源于stack exchange,提问作者0xced
相关产品推荐
相关产品推荐

