在动态语言运行时(DLR) 有表达的一些很酷的代码,其中包括一些非常漂亮的代码打印出来,我想使用,使表达式树:
int a = 1; int b = 2; Expression> expression = (c) => a + (b * c) expression.Evaluate(5, stringBuilder)
输出:
(5) => a + (b * c) = 11 Where a = 1 b * c = 10 Where b = 2 c = 5
我在网上发现了一些代码,但发现只有表达式没有参数时它才有效.
http://incrediblejourneysintotheknown.blogspot.com/2009/02/displaying-nested-evaluation-tree-from.html
然后我发现了类似方法的DLR实现.然而,DLR有自己的Expression类和许多其他标准C#类型的自定义实现,所以我有点困惑.谁知道我怎么能实现上述?
怎么样:
using System; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Text.RegularExpressions; static class Program { static void Main() { int a = 1, b = 2; StringBuilder sb = new StringBuilder(); Expression> expression = (c) => a + (b * c); expression.Evaluate(sb, 5); // now fix the capture class names (from a and b) string s = sb.ToString(); s = Regex.Replace(s, @"value\([^)]+\)\.", ""); Console.WriteLine(s); } public static void Evaluate(this LambdaExpression expr, StringBuilder builder, params object[] args) { var parameters = expr.Parameters.ToArray(); if (args == null || parameters.Length != args.Length) throw new ArgumentException("args"); Evaluate(expr.Body, 0, builder, parameters, args); } private static StringBuilder Indent(this StringBuilder builder, int depth) { for (int i = 0; i < depth; i++) builder.Append(" "); return builder; } private static void Evaluate(this Expression expr, int depth, StringBuilder builder, ParameterExpression[] parameters, object[] args) { builder.Indent(depth).Append(expr).Append(" = ").Append(Expression.Lambda(expr, parameters).Compile().DynamicInvoke(args)); UnaryExpression ue; BinaryExpression be; ConditionalExpression ce; if ((ue = expr as UnaryExpression) != null) { builder.AppendLine(" where"); Evaluate(ue.Operand, depth + 1, builder, parameters, args); } if ((be = expr as BinaryExpression) != null) { builder.AppendLine(" where"); Evaluate(be.Left, depth + 1, builder, parameters, args); Evaluate(be.Right, depth + 1, builder, parameters, args); } else if ((ce = expr as ConditionalExpression) != null) { builder.AppendLine(" where"); Evaluate(ce.Test, depth + 1, builder, parameters, args); Evaluate(ce.IfTrue, depth + 1, builder, parameters, args); Evaluate(ce.IfFalse, depth + 1, builder, parameters, args); } else { builder.AppendLine(); } } }