Expression.Compile() ,参数超出范围

Expression.Compile() , Parameter out of scope

我一直在搞乱表达式树,我遇到了挫折,找不到原因或如何解决这个问题:

        public static Expression GetExp(object caller, string s)
    {
        var callerType = caller.GetType();
        if (s.Contains('('))
        {
            //We are a method call
            var data = s.Split('.');
            var instance = Expression.Parameter(callerType, "obj");
            var currentExpression = (Expression)instance;
            for (int index = 0; index < data.Length - 1; index++)
            {
                var prop = data[index];
                currentExpression = (Expression.PropertyOrField(currentExpression, prop));
            }
            var expLex = Expression.Lambda(currentExpression, instance);
            var compiled = expLex.Compile();
            var result = compiled.DynamicInvoke(caller);
            var propType = result.GetType();
            var propField = Expression.Parameter(propType, "prop");
            var methodExpression = GetMethod(currentExpression,propType, data[data.Length - 1]);
            //What now?


            var fullExp = Expression.Lambda(methodExpression,instance);
            var fullcompiled = fullExp.Compile();
            var final =fullcompiled.DynamicInvoke(caller);

        }
        return null;
    }



    public static MethodCallExpression GetMethod(Expression callingExp,Type owner, string method)
    {
        //parameters = null
        var start = method.IndexOf('(');
        var end = method.LastIndexOf(')');
        string methodName = method.Substring(0, start);
        var amount = end - start; ;
        var methodInfo = owner.GetMethod(methodName,BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
        if (amount <= 1)
        {
            return Expression.Call(callingExp, methodInfo);
        }
        var parameters = methodInfo.GetParameters().Select(v => Expression.Parameter(v.ParameterType, v.Name)).Cast<Expression>().ToList();
        var ara = parameters.Cast<ParameterExpression>().ToArray();
        var result = Expression.Call(callingExp, methodInfo, Expression.Parameter(typeof(int),"something"));
        var fullExp = Expression.Lambda(result);
        var c = fullExp.Compile();
        return result;
    }

基本上,当我在 GetMethod 调用中调用 Compile 时,我得到了一个超出范围的参数。只有当方法有参数时才会发生这种情况,如果方法没有参数,它工作得很好。

我做错了什么?

我猜你正在获取从 scopr 引用的参数 "obj" 但它未定义错误..

这是修复它的方法。 在您的 GetMethod 方法中更改以下行。从 GetExp 方法传递参数表达式参数。

public static MethodCallExpression GetMethod(Expression callingExp, Type owner, string method,ParameterExpression param)

在下面的行中将此参数表达式作为参数传递

Expression.Lambda(result,param);

在您的 GetMethod 中更改以下行。以相同的方法传递上面创建的参数表达式实例。

var methodExpression = GetMethod(currentExpression, propType, data[data.Length - 1], instance);