コード例 #1
0
        public EnumOperationMethodInfo(Type lhs, CodeBinaryOperatorType operation, Type rhs, bool isZero)
        {
            // only 5 arithmetic cases (U = underlying type of E):
            //    E = E + U
            //    E = U + E
            //    U = E - E
            //    E = E - U
            //    E = U - E
            // plus 5 comparison cases
            //    E == E
            //    E < E
            //    E <= E
            //    E > E
            //    E >= E
            // either E can be nullable

            op = operation;

            // parameters are easy -- they are the same as the type passed in
            expectedParameters = new ParameterInfo[2];
            expectedParameters[0] = new SimpleParameterInfo(lhs);
            expectedParameters[1] = new SimpleParameterInfo(rhs);

            // compute return type (depends on type of operation)
            // start by getting the types without Nullable<>
            bool lhsNullable = ConditionHelper.IsNullableValueType(lhs);
            bool rhsNullable = ConditionHelper.IsNullableValueType(rhs);
            lhsBaseType = (lhsNullable) ? Nullable.GetUnderlyingType(lhs) : lhs;
            rhsBaseType = (rhsNullable) ? Nullable.GetUnderlyingType(rhs) : rhs;
            // determine the underlying types for both sides
            if (lhsBaseType.IsEnum)
                lhsRootType = EnumHelper.GetUnderlyingType(lhsBaseType);
            else
                lhsRootType = lhsBaseType;

            if (rhsBaseType.IsEnum)
                rhsRootType = EnumHelper.GetUnderlyingType(rhsBaseType);
            else
                rhsRootType = rhsBaseType;

            switch (op)
            {
                case CodeBinaryOperatorType.Add:
                    // add always produces an enum, except enum + enum
                    if ((lhsBaseType.IsEnum) && (rhs.IsEnum))
                        resultBaseType = lhsRootType;
                    else if (lhsBaseType.IsEnum)
                        resultBaseType = lhsBaseType;
                    else
                        resultBaseType = rhsBaseType;
                    // if either side is nullable, result is nullable
                    resultIsNullable = (lhsNullable || rhsNullable);
                    resultType = (resultIsNullable) ? typeof(Nullable<>).MakeGenericType(resultBaseType) : resultBaseType;
                    break;
                case CodeBinaryOperatorType.Subtract:
                    // subtract can be an enum or the underlying type
                    if (rhsBaseType.IsEnum && lhsBaseType.IsEnum)
                    {
                        resultRootType = rhsRootType;
                        resultBaseType = rhsRootType;
                    }
                    else if (lhsBaseType.IsEnum)
                    {
                        // special case for E - 0
                        // if 0 is the underlying type, then use E - U
                        // if not the underlying type, then 0 becomes E, use E - E
                        resultRootType = lhsRootType;
                        if (isZero && rhsBaseType != lhsRootType)
                            resultBaseType = lhsRootType;
                        else
                            resultBaseType = lhsBaseType;
                    }
                    else    // rhsType.IsEnum
                    {
                        // special case for 0 - E
                        // in all cases 0 becomes E, use E - E
                        resultRootType = rhsRootType;
                        if (isZero)
                            resultBaseType = rhsRootType;
                        else
                            resultBaseType = rhsBaseType;
                    }
                    resultIsNullable = (lhsNullable || rhsNullable);
                    resultType = (resultIsNullable) ? typeof(Nullable<>).MakeGenericType(resultBaseType) : resultBaseType;
                    break;
                case CodeBinaryOperatorType.ValueEquality:
                case CodeBinaryOperatorType.LessThan:
                case CodeBinaryOperatorType.LessThanOrEqual:
                case CodeBinaryOperatorType.GreaterThan:
                case CodeBinaryOperatorType.GreaterThanOrEqual:
                    resultType = typeof(bool);
                    break;
            }
        }
コード例 #2
0
        public LiftedArithmeticOperatorMethodInfo(MethodInfo method)
            : base(method)
        {
            Debug.Assert(expectedParameters.Length == 2, "not 2 parameters");

            // modify parameters (exactly 2, both need to be lifted)
            ParameterInfo[] actualParameters = method.GetParameters();
            expectedParameters = new ParameterInfo[2];
            expectedParameters[0] = new SimpleParameterInfo(actualParameters[0]);
            expectedParameters[1] = new SimpleParameterInfo(actualParameters[1]);

            // modify result
            resultType = typeof(Nullable<>).MakeGenericType(method.ReturnType);
        }
コード例 #3
0
        public LiftedRelationalOperatorMethodInfo(MethodInfo method)
            : base(method)
        {
            Debug.Assert(method.ReturnType == typeof(bool), "not a bool result");
            Debug.Assert(expectedParameters.Length == 2, "not 2 parameters");

            // modify parameters (exactly 2, both need to be lifted)
            ParameterInfo[] actualParameters = method.GetParameters();
            expectedParameters = new ParameterInfo[2];
            expectedParameters[0] = new SimpleParameterInfo(actualParameters[0]);
            expectedParameters[1] = new SimpleParameterInfo(actualParameters[1]);

            // set the result type
            resultType = typeof(bool);
        }
コード例 #4
0
        public LiftedConversionMethodInfo(MethodInfo method)
            : base(method)
        {
            Debug.Assert(expectedParameters.Length == 1, "not 1 parameters");

            // modify result
            resultType = typeof(Nullable<>).MakeGenericType(method.ReturnType);

            // modify parameter (exactly 1)
            ParameterInfo[] actualParameters = method.GetParameters();
            expectedParameters = new ParameterInfo[1];
            expectedParameters[0] = new SimpleParameterInfo(actualParameters[0]);
        }