public class ParameterRebinder : ExpressionVisitor
{
private ParameterExpression oldParameter;
private ParameterExpression newParameter;
protected ParameterRebinder(ParameterExpression oldParameter, ParameterExpression newParameter)
{
this.oldParameter = oldParameter;
this.newParameter = newParameter;
}
public Expression Rebind(Expression expr)
{
return Visit(expr);
}
public static Expression Rebind(Expression expr, ParameterExpression oldParameter, ParameterExpression newParameter)
{
return new ParameterRebinder(oldParameter, newParameter).Visit(expr);
}
protected override Expression VisitParameter(ParameterExpression node)
{
return (node.Name == oldParameter.Name) ? newParameter : node;
}
protected override Expression VisitConstant(ConstantExpression node)
{
return base.VisitConstant(node);
}
protected override Expression VisitMember(MemberExpression node)
{
return node.Update(Visit(node.Expression));
}
protected override Expression VisitIndex(IndexExpression node)
{
return node.Update(Visit(node), Visit(node.Arguments));
}
protected override Expression VisitUnary(UnaryExpression node)
{
return node.Update(Visit(node.Operand));
}
protected override Expression VisitBinary(BinaryExpression node)
{
return node.Update(Visit(node.Left), node.Conversion, Visit(node.Right));
}
protected override Expression VisitConditional(ConditionalExpression node)
{
return node.Update(Visit(node.Test), Visit(node.IfTrue), Visit(node.IfFalse));
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
return node.Update(Visit(node.Object), Visit(node.Arguments));
}
protected override Expression VisitInvocation(InvocationExpression node)
{
return node.Update(Visit(node.Expression), Visit(node.Arguments));
}
protected override Expression VisitLambda<T>(Expression<T> node)
{
return node.Update(Visit(node.Body), node.Parameters.Select(param => (ParameterExpression)Visit(param)));
}
}