InvalidOperationException (Lambda parameter not in scope) when trying to Compile a Lambda Expression
- by Moshe Levi
Hello,
I'm writing an Expression Parser to make my API more refactor friendly and less error prone.
basicaly, I want the user to write code like that:
repository.Get(entity => entity.Id == 10);
instead of:
repository.Get<Entity>("Id", 10);
Extracting the member name from the left side of the binary expression was straight forward.
The problems began when I tried to extract the value from the right side of the expression.
The above snippet demonstrates the simplest possible case which involves a constant value
but it can be much more complex involving closures and what not.
After playing with that for some time I gave up on trying to cover all the possible cases myself
and decided to use the framework to do all the heavy lifting for me by compiling and executing the right side of the expression.
the relevant part of the code looks like that:
public static KeyValuePair<string, object> Parse<T>(Expression<Func<T, bool>> expression)
{
var binaryExpression = (BinaryExpression)expression.Body;
string memberName = ParseMemberName(binaryExpression.Left);
object value = ParseValue(binaryExpression.Right);
return new KeyValuePair<string, object>(memberName, value);
}
private static object ParseValue(Expression expression)
{
Expression conversionExpression = Expression.Convert(expression, typeof(object));
var lambdaExpression = Expression.Lambda<Func<object>>(conversionExpression);
Func<object> accessor = lambdaExpression.Compile();
return accessor();
}
Now, I get an InvalidOperationException (Lambda parameter not in scope) in the Compile line. when I googled for the solution I came up with similar questions that involved building an expression by hand and not supplying all the pieces, or trying to rely on parameters having the same name and not the same reference. I don't think that this is the case here because I'm reusing the given expression.
I would appreciate if someone will give me some pointers on this.
Thank you.