using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace WCS.Core { public static class ExpressionExtensions { public static string ExpToString(this LambdaExpression source) { var str = ""; try { str= LambdaToString(source); } catch { str = source.ToString(); } var arr = str.Split("Convert("); arr = arr.Select(v => { if (!v.Contains(',')) return v; var index = v.IndexOf(','); var index2 = v.IndexOf(')', index); var sub = v.Substring(index, index2 - index + 1); var str = v.Replace(sub, ""); return str; }).ToArray(); var res = string.Join("", arr); return res; } public static string LambdaToString(LambdaExpression expression) { var replacements = new Dictionary(); WalkExpression(replacements, expression); string body = expression.ToString(); foreach (var parm in expression.Parameters) { var parmName = parm.Name; var parmTypeName = parm.Type.Name; body = body.Replace(parmName + " =>", "(" + parmTypeName + " v) =>"); } foreach (var replacement in replacements) { body = body.Replace(replacement.Key, replacement.Value); } return body; } private static void WalkExpression(Dictionary replacements, Expression expression) { switch (expression.NodeType) { case ExpressionType.MemberAccess: string replacementExpression = expression.ToString(); if (replacementExpression.Contains("value(")) { string replacementValue = Expression.Lambda(expression).Compile().DynamicInvoke().ToString(); if (!replacements.ContainsKey(replacementExpression)) { replacements.Add(replacementExpression, replacementValue.ToString()); } } break; case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.OrElse: case ExpressionType.AndAlso: case ExpressionType.Equal: case ExpressionType.NotEqual: var bexp = expression as BinaryExpression; WalkExpression(replacements, bexp.Left); WalkExpression(replacements, bexp.Right); break; case ExpressionType.Call: var mcexp = expression as MethodCallExpression; foreach (var argument in mcexp.Arguments) { WalkExpression(replacements, argument); } break; case ExpressionType.Lambda: var lexp = expression as LambdaExpression; WalkExpression(replacements, lexp.Body); break; case ExpressionType.Constant: //do nothing break; case ExpressionType.Convert: var exp = expression as UnaryExpression; WalkExpression(replacements, exp.Operand); break; default: //Trace.WriteLine("Unknown type"); break; } } static bool When(this T source, Expression> exp) where T : class { var str = exp.ExpToString(); try { var res = exp.Compile().Invoke(source); str += res ? " 成立" : " 不成立"; return res; } catch (Exception ex) { str += ex.GetBaseException().Message; throw; } finally { Console.WriteLine(str); Console.WriteLine("------------------------------------"); } } } }