ExpressionExtensions.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace WCS.Core
  8. {
  9. public static class ExpressionExtensions
  10. {
  11. public static string ExpToString(this LambdaExpression source)
  12. {
  13. var str = "";
  14. try
  15. {
  16. str= LambdaToString(source);
  17. }
  18. catch
  19. {
  20. str = source.ToString();
  21. }
  22. var arr = str.Split("Convert(");
  23. arr = arr.Select(v =>
  24. {
  25. if (!v.Contains(','))
  26. return v;
  27. var index = v.IndexOf(',');
  28. var index2 = v.IndexOf(')', index);
  29. var sub = v.Substring(index, index2 - index + 1);
  30. var str = v.Replace(sub, "");
  31. return str;
  32. }).ToArray();
  33. var res = string.Join("", arr);
  34. return res;
  35. }
  36. public static string LambdaToString(LambdaExpression expression)
  37. {
  38. var replacements = new Dictionary<string, string>();
  39. WalkExpression(replacements, expression);
  40. string body = expression.ToString();
  41. foreach (var parm in expression.Parameters)
  42. {
  43. var parmName = parm.Name;
  44. var parmTypeName = parm.Type.Name;
  45. body = body.Replace(parmName + " =>", "(" + parmTypeName + " v) =>");
  46. }
  47. foreach (var replacement in replacements)
  48. {
  49. body = body.Replace(replacement.Key, replacement.Value);
  50. }
  51. return body;
  52. }
  53. private static void WalkExpression(Dictionary<string, string> replacements, Expression expression)
  54. {
  55. switch (expression.NodeType)
  56. {
  57. case ExpressionType.MemberAccess:
  58. string replacementExpression = expression.ToString();
  59. if (replacementExpression.Contains("value("))
  60. {
  61. string replacementValue = Expression.Lambda(expression).Compile().DynamicInvoke().ToString();
  62. if (!replacements.ContainsKey(replacementExpression))
  63. {
  64. replacements.Add(replacementExpression, replacementValue.ToString());
  65. }
  66. }
  67. break;
  68. case ExpressionType.GreaterThan:
  69. case ExpressionType.GreaterThanOrEqual:
  70. case ExpressionType.LessThan:
  71. case ExpressionType.LessThanOrEqual:
  72. case ExpressionType.OrElse:
  73. case ExpressionType.AndAlso:
  74. case ExpressionType.Equal:
  75. case ExpressionType.NotEqual:
  76. var bexp = expression as BinaryExpression;
  77. WalkExpression(replacements, bexp.Left);
  78. WalkExpression(replacements, bexp.Right);
  79. break;
  80. case ExpressionType.Call:
  81. var mcexp = expression as MethodCallExpression;
  82. foreach (var argument in mcexp.Arguments)
  83. {
  84. WalkExpression(replacements, argument);
  85. }
  86. break;
  87. case ExpressionType.Lambda:
  88. var lexp = expression as LambdaExpression;
  89. WalkExpression(replacements, lexp.Body);
  90. break;
  91. case ExpressionType.Constant:
  92. //do nothing
  93. break;
  94. case ExpressionType.Convert:
  95. var exp = expression as UnaryExpression;
  96. WalkExpression(replacements, exp.Operand);
  97. break;
  98. default:
  99. //Trace.WriteLine("Unknown type");
  100. break;
  101. }
  102. }
  103. static bool When<T>(this T source, Expression<Func<T, bool>> exp) where T : class
  104. {
  105. var str = exp.ExpToString();
  106. try
  107. {
  108. var res = exp.Compile().Invoke(source);
  109. str += res ? " 成立" : " 不成立";
  110. return res;
  111. }
  112. catch (Exception ex)
  113. {
  114. str += ex.GetBaseException().Message;
  115. throw;
  116. }
  117. finally
  118. {
  119. Console.WriteLine(str);
  120. Console.WriteLine("------------------------------------");
  121. }
  122. }
  123. }
  124. }