I need to create a dynamic linq expression an i started work with many examples. I tested some and some work and some not. In this case i want to create a method that looks like :
public bool Check(int intvar)
{
if ( i > 2 )
return true;
else
return false;
}
Now i have written the following :
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);
Now it throws InvalidOperationException
:
Cannot jump to the label "label"`
What is wrong ? I only need a return true or false.
You need to change a few things:
Put the return label at the bottom of your function in a block expression, as René suggested. This is where your return
statement will jump.
Declare the Lambda as type Func<int, bool>
. Since you want a return value, this needs to be a function, not an action.
Declare the returnTarget
label as type bool
. Since the return value of a block expression is the value of its last statement, the label must be of the correct type.
Provide a default value for the final label (= the return value of your function if the label is reached by normal control flow instead of a return
statement).
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"