I have the below class
public class TestClass
{
public int TestProperty { get; set; }
}
I have the below code
int x = 1;
Expression<Func<TestClass, bool>> predicate = c => c.TestProperty == x;
Console.WriteLine(predicate.ToString());
The predicate.ToString()
is returning c => (c.TestProperty == value(Program <>c__DisplayClass0_0).x)
Is there any way to evaluate the Expression in order to return c => (c.TestProperty == 1)
Note that it is not possible to create the expression with the value of x set as shown below
Expression<Func<TestClass, bool>> predicate = c => c.TestProperty == 1;
CodePudding user response:
It is not very easy and robust (relies on current expression generation patterns) but can be achieved with visitor:
class MySimpleConstantReplacingVisitor : ExpressionVisitor
{
protected override Expression VisitMember(MemberExpression node)
{
if (node.Expression is ConstantExpression ce && node.Member is FieldInfo fe) // possibly check as PropertyInfo JIC
{
return Expression.Constant(fe.GetValue(ce.Value));
}
return base.VisitMember(node);
}
}
And usage:
int xx = 1;
Expression<Func<TestClass, bool>> predicate = c => c.TestProperty == xx;
var modifiedExpression = new MySimpleConstantReplacingVisitor().Visit(predicate);
Console.WriteLine(modifiedExpression.ToString()); // prints "c => (c.TestProperty == 1)"
Note that this covers only simple cases (like the one in the example) and potentially there could be a lot of caveats. I don't know if there are libraries which do exactly what you need but there is quite a lot of libraries which handle analyzing the expression trees. Like almost every LINQ-based ORM - for example EF Core (see ParameterExtractingExpressionVisitor
for example, check for closure part can be interesting). Or Serialize.Linq library.