Ok, here\'s a tricky one. Hopefully there is an expression guru here who can spot what I am doing wrong here, cause I am just not getting it.
I am building up expression
This is not an answer, but I hope it will help someone find the answer. I've simplified the code further so that it is just one single file and still fails in the same way. I have renamed the variables so that "x" is not used twice. I have removed the Range class and replaced it with hardcoded constants 0 and 1.
using System;
using System.Linq;
using System.Linq.Expressions;
class Program
{
static Expression> And(Expression> first,
Expression> second)
{
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.AndAlso(Expression.Invoke(first, x), Expression.Invoke(second, x));
return Expression.Lambda>(body, x);
}
static Expression> GetPredicateFor(Expression> selector)
{
var param = Expression.Parameter(typeof(int), "y");
var member = Expression.Invoke(selector, param);
Expression body =
Expression.AndAlso(
Expression.GreaterThanOrEqual(member, Expression.Constant(0, typeof(int))),
Expression.LessThanOrEqual(member, Expression.Constant(1, typeof(int))));
return Expression.Lambda>(body, param);
}
static void Main()
{
Expression> predicate = a => true;
predicate = And(predicate, GetPredicateFor(b => b)); // Comment out this line and it will run without error
var z = predicate.Compile();
}
}
The expression looks like this in the debugger:
x => (Invoke(a => True,x) && Invoke(y => ((Invoke(b => b,y) >= 0) && (Invoke(b => b,y) <= 1)),x))
Update: I've simplified it down to about the most simple it can be while still throwing the same exception:
using System;
using System.Linq;
using System.Linq.Expressions;
class Program
{
static void Main()
{
Expression> selector = b => true;
ParameterExpression param = Expression.Parameter(typeof(int), "y");
InvocationExpression member = Expression.Invoke(selector, param);
Expression body = Expression.AndAlso(member, member);
Expression> predicate = Expression.Lambda>(body, param);
var z = predicate.Compile();
}
}