InvertVisitor.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. namespace ExpressionKit.Unwrap
  2. {
  3. using System;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. /// <summary>
  7. /// An expression visitor that inverts all
  8. /// logic in an expression tree.
  9. /// </summary>
  10. internal class InvertVisitor : ExpressionVisitor
  11. {
  12. private static Expression Invert(Expression e)
  13. {
  14. return Expression.Equal(e, Expression.Constant(false));
  15. }
  16. protected override Expression VisitBinary(BinaryExpression b)
  17. {
  18. switch (b.NodeType)
  19. {
  20. case ExpressionType.AndAlso:
  21. return Expression.OrElse(
  22. this.Visit(b.Left),
  23. this.Visit(b.Right));
  24. case ExpressionType.OrElse:
  25. return Expression.AndAlso(
  26. this.Visit(b.Left),
  27. this.Visit(b.Right));
  28. case ExpressionType.Equal:
  29. return Expression.NotEqual(
  30. b.Left,
  31. b.Right);
  32. case ExpressionType.NotEqual:
  33. return Expression.Equal(
  34. b.Left,
  35. b.Right);
  36. case ExpressionType.GreaterThanOrEqual:
  37. return Expression.LessThan(
  38. b.Left,
  39. b.Right);
  40. case ExpressionType.GreaterThan:
  41. return Expression.LessThanOrEqual(
  42. b.Left,
  43. b.Right);
  44. case ExpressionType.LessThanOrEqual:
  45. return Expression.GreaterThan(
  46. b.Left,
  47. b.Right);
  48. case ExpressionType.LessThan:
  49. return Expression.GreaterThanOrEqual(
  50. b.Left,
  51. b.Right);
  52. default:
  53. return b;
  54. }
  55. }
  56. protected override Expression VisitUnary(UnaryExpression u)
  57. {
  58. switch (u.NodeType)
  59. {
  60. case ExpressionType.IsTrue:
  61. return Invert(u.Operand);
  62. case ExpressionType.IsFalse:
  63. case ExpressionType.Not:
  64. return u.Operand;
  65. default:
  66. return u;
  67. }
  68. }
  69. protected override Expression VisitMember(MemberExpression m)
  70. {
  71. if (m.Type != typeof(bool))
  72. return base.VisitMember(m);
  73. return Invert(m);
  74. }
  75. protected override Expression VisitMethodCall(
  76. MethodCallExpression m)
  77. {
  78. if (m.Type != typeof(bool))
  79. return base.VisitMethodCall(m);
  80. return Invert(m);
  81. }
  82. protected override Expression VisitConditional(
  83. ConditionalExpression c)
  84. {
  85. return Expression.Condition(
  86. c.Test,
  87. c.IfFalse,
  88. c.IfTrue);
  89. }
  90. protected override Expression VisitConstant(
  91. ConstantExpression c)
  92. {
  93. if (c.Type != typeof(bool))
  94. return base.VisitConstant(c);
  95. var val = (bool)c.Value;
  96. return Expression.Constant(!val);
  97. }
  98. protected override Expression VisitDefault(
  99. DefaultExpression d)
  100. {
  101. if (d.Type != typeof(bool))
  102. return base.VisitDefault(d);
  103. return Expression.Constant(true);
  104. }
  105. protected override Expression VisitDynamic(
  106. DynamicExpression d)
  107. {
  108. if (d.Type != typeof(bool))
  109. return base.VisitDynamic(d);
  110. return Invert(d);
  111. }
  112. }
  113. }