如何创建循环表达式树

How to create a loop expression tree

我正在尝试创建一个可以生成此方法的表达式树:

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;
        }

我不明白 LabelTarget works.In 我的情况如何没有我想跳转到的值...我不明白为什么它确实需要 type .

到目前为止,这是我的代码:

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;
        }

我不断收到此错误:

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

当您在块中使用 VariableExpression 时,您必须将该变量传递给 Expression.Blockvariables 参数。这就是导致您出错的原因。

恐怕我没有时间详细查看您的代码,但我使用表达式重写了您的 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();