具有返回值的动态Linq表达式

sve*_*ven 11 c# expression-trees

我需要创建一个动态的linq表达式,我开始使用许多示例.我测试了一些和一些工作而一些没有.在这种情况下,我想创建一个看起来像这样的方法:

public bool Check(int intvar)
{
   if ( i > 2 )
     return true;
   else
     return false;
}
Run Code Online (Sandbox Code Playgroud)

现在我写了以下内容:

LabelTarget returnTarget = Expression.Label("label");
ParameterExpression para = Expression.Parameter(typeof(int), "intvalue");
Expression test = Expression.GreaterThan(para, Expression.Constant(5));
Expression iftrue = Expression.Return(returnTarget, Expression.Constant(true));
Expression iffalse = Expression.Return(returnTarget,                   Expression.Constant(false));
Expression.IfThenElse(test, iftrue, iffalse);

this.TheExpression = Expression.IfThenElse(test, iftrue, iffalse);
Expression.Lambda<Action<int>>(
this.TheExpression,
new ParameterExpression[] { para }
).Compile()(5);
Run Code Online (Sandbox Code Playgroud)

现在它抛出InvalidOperationException:

无法跳转到标签"标签"`

怎么了 ?我只需要返回true或false.

Hei*_*nzi 18

你需要改变一些事情:

  • René建议将返回标签放在块表达式的函数底部.这是您的return声明将跳跃的地方.

  • 将Lambda声明为类型Func<int, bool>.由于您需要返回值,因此这需要是一个函数,而不是一个操作.

  • returnTarget标签声明为类型bool.由于块表达式的返回值是其最后一个语句的值,因此标签必须是正确的类型.

  • 为最终标签提供默认值(=如果通过正常控制流而不是return语句到达标签,则返回函数的返回值).

    LabelTarget returnTarget = Expression.Label(typeof(bool));
    ParameterExpression para = Expression.Parameter(typeof(int), "intvalue");
    Expression test = Expression.GreaterThan(para, Expression.Constant(5));
    Expression iftrue = Expression.Return(returnTarget, Expression.Constant(true));
    Expression iffalse = Expression.Return(returnTarget, Expression.Constant(false));
    
    var ex = Expression.Block(
        Expression.IfThenElse(test, iftrue, iffalse),
        Expression.Label(returnTarget, Expression.Constant(false)));
    
    var compiled = Expression.Lambda<Func<int, bool>>(
        ex,
        new ParameterExpression[] { para }
    ).Compile();
    
    Console.WriteLine(compiled(5));     // prints "False"
    Console.WriteLine(compiled(6));     // prints "True"
    
    Run Code Online (Sandbox Code Playgroud)

  • 如果你看一些编译好的IL代码,你会发现它从未真正离开...;) (7认同)