如何处理表达式树中的闭包和静态方法调用?

时间:2017-10-26 18:03:10

标签: c# lambda delegates closures expression-trees

以下代码尝试创建一个Func委托,该委托从原始的func Argument Type转换为另一种类型。

    public static Delegate Convert<T1, R>(this Func<T1, R> func, Type argType)
    {
       var param = Expression.Parameter(argType);
       var convertedParam = new Expression[] { Expression.Convert(param, typeof(T1))};

        var call = Expression.Convert(
            func.Target == null || func.Target is Closure
                ? Expression.Call(func.Method, Expression.Constant(func.Target), convertedParam[0])// this path causes the error
                : Expression.Call(Expression.Constant(func.Target), func.Method, convertedParam), typeof(R));

        var delegateType = typeof(Func<,>).MakeGenericType(argType, typeof(R));
        var lambda = Expression.Lambda(delegateType, call, param);
        return lambda.Compile();// BUG: 'MethodInfo must be a runtime MethodInfo object.

    }

当Func包含一个闭包作为Target时,我的问题开始了,lambda.Compile()错误说“方法信息必须是运行时MethodInfo对象”我怀疑它是因为该方法是静态的。

有人可以向我解释我做错了什么吗?为什么?我显然不能很好地理解表达式,以便我自己解决这个问题。

提前致谢。

1 个答案:

答案 0 :(得分:4)

您应该致电Expression.Invoke,直接致电代表。

传递Expression.Constant(func)