【问题标题】:Expression.Compile() , Parameter out of scopeExpression.Compile() ,参数超出范围
【发布时间】:2015-09-13 14:03:57
【问题描述】:

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

        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 时,我得到了一个超出范围的参数。只有当方法有参数时才会发生这种情况,如果方法没有参数,它就可以正常工作。

我做错了什么?

【问题讨论】:

    标签: c# delegates expression-trees


    【解决方案1】:

    我猜你得到的是从 scopr 引用的参数“obj”,但它没有定义错误..

    这里是你可以解决它的方法。 在您的 GetMethod Method 更改下面的行。从您的 GetExp 方法传递参数表达式参数。

    public static MethodCallExpression GetMethod(表达式 callExp,类型所有者,字符串方法,ParameterExpression 参数)

    在下面的行中传递这个参数表达式作为参数

    Expression.Lambda(result,param);

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

    var methodExpression = GetMethod(currentExpression, propType, 数据[data.Length - 1], 实例);

    【讨论】:

    • 谢谢!这给了我修复它所需的所有信息:D
    猜你喜欢
    • 2014-01-25
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多