如何创建循环表达式树

问题描述 投票:0回答:1

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

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是如何工作的。在我的情况下,没有价值我想跳到......我不明白为什么它需要一个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'
c# loops .net-core expression-trees
1个回答
0
投票

当你在一个块中使用VariableExpression时,你必须将该变量传递给variablesExpression.Block参数。这就是导致错误的原因。

我担心我没有时间仔细检查你的代码,但是我用表达式重写了你的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();
© www.soinside.com 2019 - 2024. All rights reserved.