protected override Expression VisitUnary(UnaryExpression unaryExpression) { Check.NotNull(unaryExpression, nameof(unaryExpression)); if (unaryExpression.NodeType == ExpressionType.Not && unaryExpression.IsLogicalNot()) { if (unaryExpression.Operand is ConstantExpression innerConstant && innerConstant.Value is bool value) { // !(true) -> false // !(false) -> true return(Expression.Constant(!value)); } if (unaryExpression.Operand is UnaryExpression innerUnary && innerUnary.NodeType == ExpressionType.Not) { // !(!a) -> a return(Visit(innerUnary.Operand)); } if (unaryExpression.Operand is BinaryExpression innerBinary) { // De Morgan's if (innerBinary.NodeType == ExpressionType.AndAlso || innerBinary.NodeType == ExpressionType.OrElse) { return(Visit( Expression.MakeBinary( Negate(innerBinary.NodeType), Expression.Not(innerBinary.Left), Expression.Not(innerBinary.Right)))); } if (TryNegate(innerBinary.NodeType, out var negated)) { return(Visit( Expression.MakeBinary( negated, innerBinary.Left, innerBinary.Right))); } } } return(base.VisitUnary(unaryExpression)); }