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)