Guest User

Untitled

a guest
Oct 18th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.58 KB | None | 0 0
  1. static void Main()
  2. {
  3. Expression<Func<Hoge, Hoge>> expression = x => new Hoge(x.i + 9)
  4. {
  5. a = new[] { 8, 9, x.i * 2 }
  6. };
  7.  
  8. expression.Dump();
  9.  
  10. var value = new Hoge(10);
  11.  
  12. var rewrited = Rewrite(expression, value);
  13.  
  14. rewrited.Dump();
  15.  
  16. var d = (Func<Hoge>)rewrited.Compile();
  17. var instance = d();
  18.  
  19. instance.Dump();
  20. }
  21.  
  22. public static Expression<Func<T>> Rewrite<T>(
  23. Expression<Func<T, T>> expression,
  24. T value)
  25. {
  26. var visitor = new ExpressionRewriter<T>(value, expression.Parameters[0]);
  27.  
  28. var rewrited = visitor.Visit(expression.Body);
  29. var newLambda = Expression.Lambda<Func<T>>(rewrited);
  30.  
  31. return newLambda;
  32. }
  33.  
  34. class Hoge
  35. {
  36. public Hoge(int i)
  37. {
  38. this.i = i;
  39. }
  40.  
  41. public int i { get; }
  42.  
  43. public int[] a { get; set; }
  44. }
  45.  
  46. class ExpressionRewriter<T> :
  47. ExpressionVisitor
  48. {
  49. private readonly T _original;
  50.  
  51. private readonly ParameterExpression _parameter;
  52.  
  53. private Dictionary<MemberInfo, ConstantExpression> _cache =
  54. new Dictionary<MemberInfo, ConstantExpression>();
  55.  
  56. public ExpressionRewriter(
  57. T original,
  58. ParameterExpression parameter)
  59. {
  60. this._original = original;
  61. this._parameter = parameter;
  62. }
  63.  
  64. protected override Expression VisitMember(
  65. MemberExpression node)
  66. {
  67. if (node.Expression != this._parameter)
  68. {
  69. return node;
  70. }
  71.  
  72. var member = node.Member;
  73.  
  74. if (!this._cache.TryGetValue(member, out var evaluatedExpression))
  75. {
  76. var lambda = Expression.Lambda(node, this._parameter);
  77. var d = lambda.Compile();
  78. object value = d.DynamicInvoke(this._original);
  79.  
  80. this._cache[member] = evaluatedExpression = Expression.Constant(value);
  81. }
  82.  
  83. return evaluatedExpression;
  84. }
  85. }
Add Comment
Please, Sign In to add comment