Esempio n. 1
0
        public static Expression ImplicitNullableConversion(ParseContext ec, Expression expr, Type targetType)
        {
            Type exprType = expr.Type;

            //
            // From null to any nullable type
            //
            if (exprType == TypeManager.CoreTypes.Null)
            {
                return(ec == null ? EmptyExpression.Null : LiftedNullExpression.Create(targetType, expr.Span));
            }

            // S -> T?
            var elementType = targetType.GetGenericArguments()[0];

            // S? -> T?
            if (TypeManager.IsNullableType(exprType))
            {
                exprType = exprType.GetGenericArguments()[0];
            }

            //
            // Predefined implicit identity or implicit numeric conversion
            // has to exist between underlying type S and underlying type T
            //

            // Handles probing
            if (ec == null)
            {
                if (exprType == elementType)
                {
                    return(EmptyExpression.Null);
                }

                return(MakeImplicitNumericConversion(ec, null, exprType, elementType));
            }

            Expression unwrap;

            if (exprType != expr.Type)
            {
                unwrap = Unwrap.Create(expr);
            }
            else
            {
                unwrap = expr;
            }

            Expression conv = exprType == elementType ? unwrap : MakeImplicitNumericConversion(ec, unwrap, exprType, elementType);

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

            if (exprType != expr.Type)
            {
                return(new LiftedExpression(conv, unwrap, targetType).Resolve(ec));
            }

            // Do constant optimization for S -> T?
            if (unwrap is ConstantExpression)
            {
                conv = ((ConstantExpression)unwrap).ConvertImplicitly(elementType);
            }

            return(Wrap.Create(conv, targetType));
        }