I have following code:
public class MyClass
{
Expression> Criteria {get; set;}
}
public class Customer
{
//..
publ
You can use the following helper functions (one could probably give them a better names, but that's not essential):
public static class ExpressionUtils
{
public static Expression> Bind(this Expression> source, Expression> resultSelector)
{
var body = new ParameterExpressionReplacer { source = resultSelector.Parameters[0], target = source.Body }.Visit(resultSelector.Body);
var lambda = Expression.Lambda>(body, source.Parameters);
return lambda;
}
public static Expression> ApplyTo(this Expression> source, Expression> innerSelector)
{
return innerSelector.Bind(source);
}
class ParameterExpressionReplacer : ExpressionVisitor
{
public ParameterExpression source;
public Expression target;
protected override Expression VisitParameter(ParameterExpression node)
{
return node == source ? target : base.VisitParameter(node);
}
}
}
Let see how the sample expression
c.Criteria = x => x.Name.StartsWith("SomeTexts");
can be built from the two different parts.
If you have
Expression> e = x => x.Name;
then
c.Criteria = e.Bind(x => x.StartsWith("SomeTexts"));
or if you have this instead
Expression> e = x => x.StartsWith("SomeTexts");
then
c.Criteria = e.ApplyTo((Customer x) => x.Name);
If you have both expressions, then you can use any of the two functions, since a.Bind(b)
is equivalent to b.ApplyTo(a)
.