简体   繁体   English

如何创建循环表达式树

[英]How to create a loop expression tree

I am trying to create an expression tree that would generate this method: 我正在尝试创建一个生成此方法的表达式树:

public static int Print(int i) {
            int cnt = 0;
            int sum = 0;
            while (true) {
                if (cnt >= i) {
                    Console.WriteLine(sum);
                    break;
                }
                sum = sum + cnt;
                cnt++;
            }
           return sum;
        }

I do not understand how the LabelTarget works.In my case there is no value that i want to jump to...I do not understand why it does require a type . 我不明白LabelTarget工作方式。在我的情况下,我没有要跳转的值...我不明白为什么它确实需要type

Here is my code so far: 到目前为止,这是我的代码:

public static  Func<int,int> MakeExpression() {
            //input
            ParameterExpression parameter = Expression.Parameter(typeof(int));
            //define local variables and initialize them
            Expression cntVarExpr = Expression.Variable(typeof(int),"cnt");
            Expression sumVarExpr = Expression.Variable(typeof(int), "sum");

            Expression initCntExpr = Expression.Assign(cntVarExpr, Expression.Constant(0));
            Expression initSumExpr = Expression.Assign(sumVarExpr, Expression.Constant(0));

            //loop condition
            Expression condExpr = Expression.GreaterThanOrEqual(cntVarExpr, parameter);
            //block if true
            MethodInfo method = typeof(Console).GetMethod("WriteLine",new Type[] { typeof(int)});
            Expression printExpr = Expression.Call(null, method,cntVarExpr); //static method

            LabelTarget label = Expression.Label(typeof(int)); //am not sure about this one ? what
            Expression bkExpr = Expression.Break(label, sumVarExpr);
            BlockExpression block = Expression.Block(printExpr, bkExpr);

            //loop body
            Expression ifExpr = Expression.IfThen(condExpr, block);
            Expression addExpr = Expression.AddAssign(sumVarExpr,cntVarExpr);
            Expression incrExpr = Expression.Add(cntVarExpr, Expression.Constant(1));
            BlockExpression loopBodyExpr = Expression.Block(ifExpr, addExpr,incrExpr);
            LoopExpression loopExpr = Expression.Loop(loopBodyExpr);

            //method body

            Expression returnExpr = Expression.Return(label, sumVarExpr,typeof(int));

            //final expression
            BlockExpression bigExpression = Expression.Block(initCntExpr, initSumExpr, loopExpr, returnExpr);


            var meth = Expression.Lambda<Func<int, int>>(bigExpression,parameter).Compile();
            return meth;
        }

I keep getting this error: 我一直收到这个错误:

'variable 'cnt' of type 'System.Int32' referenced from scope '', but it is not defined'

When you use a VariableExpression in a block, you have to pass that variable into the variables parameter of Expression.Block . 在块中使用VariableExpression时,必须将该变量传递给Expression.Blockvariables参数。 This is what's causing your error. 这就是导致您出错的原因。

I'm afraid I didn't have time to go through your code in detail, but I rewrote your C# using expressions: 恐怕我没有时间详细研究您的代码,但是我使用表达式重写了您的C#:

var i = Expression.Parameter(typeof(int), "i");
var cnt = Expression.Variable(typeof(int), "cnt");
var sum = Expression.Variable(typeof(int), "sum");

var writeLineMethod = typeof(Console).GetMethod("WriteLine", new[] { typeof(object) });

var breakLabel = Expression.Label("break");
var loop = Expression.Loop(
    Expression.Block(
        Expression.IfThen(
            Expression.GreaterThanOrEqual(cnt, i),
            Expression.Block(
                Expression.Call(writeLineMethod, Expression.Convert(sum, typeof(object))),
                Expression.Break(breakLabel))),
        Expression.AddAssign(sum, cnt),
        Expression.PostIncrementAssign(cnt)),
    breakLabel);

var block = Expression.Block(new[] { cnt, sum },
    Expression.Assign(cnt, Expression.Constant(0)),
    Expression.Assign(sum, Expression.Constant(0)),
    loop,
    sum);

var method = Expression.Lambda<Func<int, int>>(block, new[] { i }).Compile();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM