Ejemplo n.º 1
0
        public override object GetValue()
        {
            object value = _operand.GetValue();

            if (value == null || OperatorMethod == null)
            {
                return(null);
            }

            try
            {
                return(OperatorMethod.Invoke(null, new object[] { value }));
            }
            catch (TargetInvocationException ex)
            {
                throw ExceptionBuilder.UnaryOperatorFailed(Op, OperatorMethod, _operand.ExpressionType, value, ex.InnerException);
            }
        }
Ejemplo n.º 2
0
        public override object GetValue()
        {
            if (OperatorMethod == null)
            {
                return(null);
            }

            if (_op != BinaryOperator.LogicalAnd && _op != BinaryOperator.LogicalOr)
            {
                // Normal evaluation.
                //
                // In this case the whole expression is null when
                // left or right is null.

                object left = _left.GetValue();

                if (left == null)
                {
                    return(null);
                }

                object right = _right.GetValue();

                if (right == null)
                {
                    return(null);
                }

                try
                {
                    return(OperatorMethod.Invoke(null, new object[] { left, right }));
                }
                catch (TargetInvocationException ex)
                {
                    throw ExceptionBuilder.BinaryOperatorFailed(Op, OperatorMethod, _left.ExpressionType, _right.ExpressionType, left, right, ex.InnerException);
                }
            }
            else
            {
                // Operator is either LogicalAnd or LogicalOr.
                //
                // Special handling for three-state boolean logic and short-circuit
                // boolean evaluation.
                //
                // ATTENTION: All binary operators will return null when any operand is
                //            is null. Logical operations are different in this point.
                //            Sometimes boolean operators will return TRUE or FALSE though
                //            an operand was null.
                //
                //            See tables for details.
                //
                //    AND | F | T | N        OR | F | T | N
                //    ----+---+---+--        ---+---+---+--
                //    F   | F | F | F        F  | F | T | N
                //    T   | F | T | N        T  | T | T | T
                //    N   | F | N | N        N  | N | T | N

                object left = _left.GetValue();

                if (left != null)
                {
                    // Special handling to allow short-circuit boolean evaluation.

                    bool leftAsBool = Convert.ToBoolean(left, CultureInfo.InvariantCulture);

                    if (_op == BinaryOperator.LogicalAnd && !leftAsBool)
                    {
                        return(false);
                    }

                    if (_op == BinaryOperator.LogicalOr && leftAsBool)
                    {
                        return(true);
                    }
                }

                object right = _right.GetValue();

                if (left == null && right == null)
                {
                    return(null);
                }

                if (left != null && right != null)
                {
                    bool leftAsBool  = Convert.ToBoolean(left, CultureInfo.InvariantCulture);
                    bool rightAsBool = Convert.ToBoolean(right, CultureInfo.InvariantCulture);

                    if (_op == BinaryOperator.LogicalAnd)
                    {
                        return(leftAsBool && rightAsBool);
                    }
                    else
                    {
                        return(leftAsBool || rightAsBool);
                    }
                }
                else if (left != null)
                {
                    // left != null && right == null

                    bool leftAsBool = Convert.ToBoolean(left, CultureInfo.InvariantCulture);

                    if (_op == BinaryOperator.LogicalAnd)
                    {
                        if (leftAsBool)
                        {
                            return(null);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (leftAsBool)
                        {
                            return(true);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                else
                {
                    // left == null && right != null

                    bool rightAsBool = Convert.ToBoolean(right, CultureInfo.InvariantCulture);

                    if (_op == BinaryOperator.LogicalAnd)
                    {
                        if (rightAsBool)
                        {
                            return(null);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (rightAsBool)
                        {
                            return(true);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
            }
        }