Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda compile failure, reference defined in '' scope, but is not defined

In the simple snippet below:

static void Main(string[] args)
{
    Expression<Func<string, bool>> equal = s => s == "test";
    LambdaExpression lambda = Expression.Lambda(equal.Body, Expression.Parameter(typeof(string), "s"));
    lambda.Compile();
}

The compile method fails with an InvalidOperationException

"variable 's' of type 'System.String' referenced from scope '', but it is not defined".

While I've found other similar questions, I've failed to understand the answers provided.

The DebugView of the LambdaExpression contains this:

.Lambda #Lambda1<System.Func`2[System.String,System.Boolean]>(System.String $s) {
    $s == "test"
}

So where I've seen in other examples of this question, the parameter and the usage don't match up, this doesn't appear to be an issue here. What am I doing wrong?

like image 540
one-t Avatar asked Jan 22 '13 19:01

one-t


1 Answers

Parameters of lambda expressions don't use equality based on names, they use reference equality. So, in your expression, you have two entirely different parameters called s, one is defined but not used, the other is used but not defined.

So, basically, your expression is something like s1 => s2 == "test", which is why it fails to compile. The simplest fix would be to use the same parameter the original expression uses:

LambdaExpression lambda = Expression.Lambda(equal.Body, equal.Parameters.Single());

If you really wanted to use your own parameter, you would need to replace all instances of the original parameter in the lambda body with your new parameter. Probably the best way to do that is to use ExpressionVisitor.

like image 196
svick Avatar answered Oct 27 '22 20:10

svick