Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static void Main()
- {
- Expression<Func<Hoge, Hoge>> expression = x => new Hoge(x.i + 9)
- {
- a = new[] { 8, 9, x.i * 2 }
- };
- expression.Dump();
- var value = new Hoge(10);
- var rewrited = Rewrite(expression, value);
- rewrited.Dump();
- var d = (Func<Hoge>)rewrited.Compile();
- var instance = d();
- instance.Dump();
- }
- public static Expression<Func<T>> Rewrite<T>(
- Expression<Func<T, T>> expression,
- T value)
- {
- var visitor = new ExpressionRewriter<T>(value, expression.Parameters[0]);
- var rewrited = visitor.Visit(expression.Body);
- var newLambda = Expression.Lambda<Func<T>>(rewrited);
- return newLambda;
- }
- class Hoge
- {
- public Hoge(int i)
- {
- this.i = i;
- }
- public int i { get; }
- public int[] a { get; set; }
- }
- class ExpressionRewriter<T> :
- ExpressionVisitor
- {
- private readonly T _original;
- private readonly ParameterExpression _parameter;
- private Dictionary<MemberInfo, ConstantExpression> _cache =
- new Dictionary<MemberInfo, ConstantExpression>();
- public ExpressionRewriter(
- T original,
- ParameterExpression parameter)
- {
- this._original = original;
- this._parameter = parameter;
- }
- protected override Expression VisitMember(
- MemberExpression node)
- {
- if (node.Expression != this._parameter)
- {
- return node;
- }
- var member = node.Member;
- if (!this._cache.TryGetValue(member, out var evaluatedExpression))
- {
- var lambda = Expression.Lambda(node, this._parameter);
- var d = lambda.Compile();
- object value = d.DynamicInvoke(this._original);
- this._cache[member] = evaluatedExpression = Expression.Constant(value);
- }
- return evaluatedExpression;
- }
- }
Add Comment
Please, Sign In to add comment