构建动态表达式树时出现问题

我正在尝试构建一个动态表达式树,如下所示:

Func<IEnumerable, int, bool> dividesectionmethod = (x, y) => { int nos1 = 0; int nos2 = 0; foreach (int i in x) { if (i  nos2; }; 

为此我正在使用:

  ParameterExpression enumerableExpression = Expression.Parameter(typeof(IEnumerable), "x"); ParameterExpression intexpression = Expression.Parameter(typeof(int), "y"); ParameterExpression localvarnos1 = Expression.Variable(typeof(int), "nos1"); ParameterExpression localvarnos2 = Expression.Variable(typeof(int), "nos2"); ConstantExpression zeroConstantintval = Expression.Constant(0); BinaryExpression bexplocalnos1 = Expression.Assign(localvarnos1, zeroConstantintval); BinaryExpression bexplocalnos2 = Expression.Assign(localvarnos2, zeroConstantintval); //As Expression does not support Foreach we need to get Enumerator before doing loop ParameterExpression enumerator = Expression.Variable(typeof(IEnumerator), "enumerator"); BinaryExpression assignenumerator = Expression.Assign(enumerator, Expression.Call(enumerableExpression, typeof(IEnumerable).GetMethod("GetEnumerator"))); var currentelement = Expression.Parameter(typeof(int), "i"); var callCurrent = Expression.Assign(currentelement, Expression.Property(enumerator, "Current")); BinaryExpression firstlessequalsecond = Expression.LessThanOrEqual(currentelement, intexpression); MethodCallExpression movenext = Expression.Call(enumerator, typeof(IEnumerator).GetMethod("MoveNext")); LabelTarget looplabel = Expression.Label("looplabel"); LabelTarget returnLabel = Expression.Label(typeof(bool), "retval"); BlockExpression block = Expression.Block(enumerableExpression, intexpression, localvarnos1, localvarnos2, bexplocalnos1, bexplocalnos2, Expression.Loop(Expression.IfThenElse( Expression.NotEqual(movenext, Expression.Constant(false)), Expression.IfThenElse(firstlessequalsecond, Expression.Increment(localvarnos1), Expression.Increment(localvarnos2)),Expression.Break(looplabel)), looplabel), Expression.Return(returnLabel, Expression.LessThan(localvarnos1, localvarnos2))); Expression<Func<IEnumerable, int, bool>> lambda = Expression.Lambda<Func<IEnumerable, int, bool>>(block, Expression.Parameter(typeof(IEnumerable), "x"), Expression.Parameter(typeof(int), "y")); Func<IEnumerable, int, bool> mymethod = lambda.Compile(); 

但问题是Expression.Lambda会抛出exception:

 Expression of type 'System.Void' cannot be used for return type 'System.Boolean' 

我不知道这个问题因为我的块看起来好了:

 .Block() { $x; $y; $nos1; $nos2; $nos1 = 0; $nos2 = 0; .Loop { .If (.Call $enumerator.MoveNext() != False) { .If ($i <= $y) { .Increment($nos1) } .Else { .Increment($nos2) } } .Else { .Break looplabel { } } } .LabelTarget looplabel:; .Return retval { $nos1 < $nos2 } } 

请让我知道问题所在。

BlockExpression的值只是块中最后一个表达式的值。 不要包含ReturnExpression,只需让最后一个表达式成为您想要返回的值。

此外,您需要将块的ParameterExpressions声明为Expression.Block方法的单独参数。 您已将它们包含在表达式列表中,这将导致它们被计算为表达式,但不会在块中声明它们。

此外, Expression.Increment “不会更改传递给它的对象的值”,因此您需要将增量表达式包装在赋值表达式中。

 BlockExpression block = Expression.Block( new ParameterExpression[] { localvarnos1, localvarnos2, enumerator, currentelement }, bexplocalnos1, bexplocalnos2, assignenumerator, Expression.Loop( Expression.IfThenElse( Expression.NotEqual(movenext, Expression.Constant(false)), Expression.Block( callCurrent, Expression.IfThenElse( firstlessequalsecond, Expression.Assign( localvarnos1, Expression.Increment(localvarnos1)), Expression.Assign( localvarnos2, Expression.Increment(localvarnos2)))), Expression.Break(looplabel)), looplabel), Expression.LessThan(localvarnos1, localvarnos2)); Expression, int, bool>> lambda = Expression.Lambda, int, bool>>( block, enumerableExpression, intexpression);