Reputation: 65
I'm new to C# expressions trees.
I've an expression tree being passed to a method as below:
private void MyMethod(System.Linq.Expressions.Expression exp, string param)
I need to be able to tweak this exp and add two AND clauses based on the param value at runtime. How do I achieve this please?
An example to call this method is:
var temp= MyOtherMethod(cellValue.ExpressionObj, columnName);
Thanks.
Upvotes: 0
Views: 931
Reputation: 3208
You should take a look at ExpressionVisitor class.
Good example how to use it can be found in Dissecting Linq Expression Trees - Part 2 blog post.
Expressions are immutable and you need to return new expression back to caller to use the altered one.
Long story short:
private Expression MyMethod(Expression<MyClass> exp, string param) {
if(param == "something") {
var visitor = new CustomVisitor(); /// You should implement one based on your needs
return visitor.Visit(exp);
}
}
EDIT:
public class AndAlsoVisitor : ExpressionVisitor {
protected override Expression VisitLambda<T>(Expression<T> node) {
// Make it lambda expression
var lambda = node as LambdaExpression;
// This should never happen
if (node != null) {
// Create property access
var lengthAccess = Expression.MakeMemberAccess(
lambda.Parameters[0],
lambda.Parameters[0].Type.GetProperty("Length")
);
// Create p.Length >= 10
var cond1 = Expression.LessThanOrEqual(lengthAccess, Expression.Constant(10));
// Create p.Length >= 3
var cond2 = Expression.GreaterThanOrEqual(lengthAccess, Expression.Constant(3));
// Create p.Length >= 10 && p.Length >= 3
var merged = Expression.AndAlso(cond1, cond2);
// Merge old expression with new one we have created
var final = Expression.AndAlso(lambda.Body, merged);
// Create lambda expression
var result = Expression.Lambda(final, lambda.Parameters);
// Return result
return result;
}
return null;
}
}
Upvotes: 1