When creating a lambda expression by hand I get a 'Parameter not in scope' exception.
Any ideas as to what I am doing wrong?
public class OtherType
{
public string First_Name { get; set; }
public string Last_Name { get; set; }
}
static void Main(string[] args)
{
Expression<Func<OtherType, bool>> l2 =
p => p.First_Name == "Bob";
l2.Compile(); // Works
PropertyInfo property =
typeof(OtherType).GetProperty("First_Name");
ParameterExpression para =
Expression.Parameter(typeof(OtherType), "para");
ConstantExpression right =
Expression.Constant("Bob", typeof(string));
MemberExpression left =
Expression.Property(Expression.Parameter(typeof(OtherType), "para"), property);
BinaryExpression binary =
Expression.MakeBinary(ExpressionType.Equal, left, right);
Expression<Func<OtherType, bool>> l =
Expression.Lambda<Func<OtherType, bool>>(binary, new ParameterExpression[] { para });
l.Compile(); // Get a 'Lambda Parameter not in scope' exception
}
You use a lambda expression to create an anonymous function. Use the lambda declaration operator => to separate the lambda's parameter list from its body. A lambda expression can be of any of the following two forms: Expression lambda that has an expression as its body:
An outer variable must be definitely assigned before it can be consumed in a lambda expression. The following example demonstrates these rules: A variable that is captured will not be garbage-collected until the delegate that references it becomes eligible for garbage collection.
A lambda expression is an expression of any of the following two forms: Expression lambda that has an expression as its body: (input-parameters) => expression Statement lambda that has a statement block as its body: (input-parameters) => { <sequence-of-statements> }
Beginning with C# 9.0, you can use discards to specify two or more input parameters of a lambda expression that aren't used in the expression: Lambda discard parameters may be useful when you use a lambda expression to provide an event handler.
You need to reuse the same parameter object. So where you've got:
MemberExpression left = Expression.Property
(Expression.Parameter(typeof(OtherType), "para"), property);
it should be:
MemberExpression left = Expression.Property(para, property);
I know it would make sense for them to match by name, but that's just not the way it works :(
If it's any consolation at all, I very rarely get hand-built expression trees right first time. I have to swear at them for a while. On the other hand, I believe that on cold enough days, Marc Gravell can exhale carefully and his breath will come out in the form of perfect, frosty expression tree code...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With