Created
July 5, 2017 11:30
-
-
Save e673/6d5a389c7ee87490e3e59d152b0e5ff9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Experiments | |
{ | |
class ExpressionUtil | |
{ | |
class Substitutor | |
{ | |
Expression expr; | |
Expression subst; | |
ParameterExpression[] param; | |
ParameterExpression replaced; | |
public Substitutor(LambdaExpression expr, LambdaExpression subst, int index) | |
{ | |
this.expr = expr.Body; | |
this.subst = subst.Body; | |
replaced = expr.Parameters[index]; | |
param = expr.Parameters.SelectMany((p, i) => i != index ? Enumerable.Repeat(p, 1) : subst.Parameters).ToArray(); | |
} | |
public LambdaExpression GetResult() | |
{ | |
Expression res = Traverse(expr); | |
return Expression.Lambda(res, param); | |
} | |
public Expression<T> GetResult<T>() | |
{ | |
Expression res = Traverse(expr); | |
return Expression.Lambda<T>(res, param); | |
} | |
Expression Traverse(Expression expr) | |
{ | |
switch (expr) | |
{ | |
case ParameterExpression pex: | |
return pex == replaced ? subst : pex; | |
case UnaryExpression uex: | |
return uex.Update(Traverse(uex.Operand)); | |
case BinaryExpression bex: | |
return bex.Update(Traverse(bex.Left), bex.Conversion, Traverse(bex.Right)); | |
case MethodCallExpression mcex: | |
return mcex.Update(Traverse(mcex.Object), mcex.Arguments.Select(Traverse)); | |
case LambdaExpression lex: | |
return lex; | |
case null: | |
return null; | |
default: | |
throw new NotImplementedException(); | |
} | |
} | |
} | |
public static LambdaExpression Substitute(LambdaExpression expr, LambdaExpression subst, int index) | |
{ | |
Substitutor p = new Substitutor(expr, subst, index); | |
return p.GetResult(); | |
} | |
public static Expression<T> Substitute<T>(LambdaExpression expr, LambdaExpression subst, int index) | |
{ | |
Substitutor p = new Substitutor(expr, subst, index); | |
return p.GetResult<T>(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment