Beispiel #1
0
        private Type ResolveExpressionCommonType(Type left, Type right, bool allowStringConcat, bool allowBothImplicit, bool allowObjectCoercion)
        {
            Require.NotNull(left, "left");
            Require.NotNull(right, "right");

            // No casting required.

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

            if (allowObjectCoercion)
            {
                if (left == typeof(object))
                {
                    return(right);
                }
                if (right == typeof(object))
                {
                    return(left);
                }
            }

            // Special cast for adding strings.

            if (allowStringConcat && (left == typeof(string) || right == typeof(string)))
            {
                return(typeof(string));
            }

            // Can we cast implicitly?

            var leftTable  = TypeUtil.GetImplicitCastingTable(left);
            var rightTable = TypeUtil.GetImplicitCastingTable(right);

            if (leftTable != null && rightTable != null)
            {
                // See whether one of the types appears in the other.

                foreach (var leftType in leftTable)
                {
                    if (leftType == right)
                    {
                        return(leftType);
                    }
                }

                foreach (var rightType in rightTable)
                {
                    if (rightType == left)
                    {
                        return(rightType);
                    }
                }

                // Otherwise, find the first common type.

                int lowest = int.MaxValue;

                for (int i = 0; i < leftTable.Count; i++)
                {
                    for (int j = 0; j < rightTable.Count; j++)
                    {
                        if (leftTable[i] == rightTable[j])
                        {
                            lowest = Math.Min(lowest, j);
                        }
                    }
                }

                if (lowest != int.MaxValue)
                {
                    if (
                        allowBothImplicit ||
                        (IsAllowableImplicit(left, rightTable[lowest]) && IsAllowableImplicit(right, rightTable[lowest]))
                        )
                    {
                        return(rightTable[lowest]);
                    }
                }
            }

            // We can't cast implicitly.

            throw new ExpressionsException("Cannot resolve expression type", ExpressionsExceptionType.TypeMismatch);
        }