コード例 #1
0
ファイル: TypeExt.cs プロジェクト: wendell620/Cyjb
        /// <summary>
        /// 返回 <paramref name="types"/> 中能够被其它所有类型包含的类型。
        /// </summary>
        /// <param name="types">类型集合。</param>
        /// <returns><paramref name="types"/> 中能够被其它所有类型包含的类型,如果不存在则为 <c>null</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="types"/> 为 <c>null</c>。</exception>
        /// <remarks>若 A 类型可以隐式类型转换(指预定义的类型转换)为 B 类型,那么就称 A 被 B 包含,而 B 包含 A。</remarks>
        public static Type GetEncompassedType(IEnumerable <Type> types)
        {
            if (types == null)
            {
                throw CommonExceptions.ArgumentNull("types");
            }
            Contract.EndContractBlock();
            Type encompassedType = null;

            foreach (Type type in types)
            {
                if (type == null)
                {
                    continue;
                }
                if (encompassedType == null)
                {
                    encompassedType = type;
                }
                else if (encompassedType != type)
                {
                    // 这里剔除 void 类型,但若 types 全部是 void,能够使得结果是 void。
                    if (encompassedType == typeof(void))
                    {
                        encompassedType = type;
                    }
                    else if (type != typeof(void))
                    {
                        ConversionType convType = ConversionFactory.GetStandardConversion(encompassedType, type);
                        if (convType == ConversionType.None)
                        {
                            return(null);
                        }
                        if (convType.IsExplicit())
                        {
                            encompassedType = type;
                        }
                    }
                }
            }
            return(encompassedType);
        }
コード例 #2
0
        /// <summary>
        /// 寻找与 <paramref name="type"/> 匹配的最好的类型。调用保证 <paramref name="type"/>
        /// 可以转换为 <paramref name="firstType"/> 和 <paramref name="secondType"/>。
        /// </summary>
        /// <param name="firstType">要比较匹配的第一个类型。</param>
        /// <param name="secondType">要比较匹配的第二个类型。</param>
        /// <param name="type">要进行匹配的类型。</param>
        /// <returns>如果 <paramref name="firstType"/> 与 <paramref name="type"/> 匹配的更好,则为 <c>-1</c>;
        /// 如果 <paramref name="secondType"/> 与 <paramref name="type"/> 匹配的更好,则为 <c>1</c>;
        /// 如果匹配程度相同,则为 <c>0</c>。</returns>
        /// <remarks>《CSharp Language Specification》 7.5.3.3 Better conversion from expression。</remarks>
        private int CompareType(Type firstType, Type secondType, Type type)
        {
            Contract.Requires(firstType != null && secondType != null && type != null);
            Contract.Ensures(Contract.Result <int>() >= -1 && Contract.Result <int>() <= 1);
            if (firstType == secondType)
            {
                return(0);
            }
            if (firstType == type)
            {
                return(-1);
            }
            if (secondType == type)
            {
                return(1);
            }
            bool typeByRef = type.IsByRef;

            // 根据 type 是否按引用传递,选择普通参数或按引用传递的参数。
            if (firstType.IsByRef)
            {
                firstType = firstType.GetElementType();
                if (secondType.IsByRef)
                {
                    secondType = secondType.GetElementType();
                }
                else if (firstType == secondType)
                {
                    return(typeByRef ? -1 : 1);
                }
            }
            else if (secondType.IsByRef)
            {
                secondType = secondType.GetElementType();
                if (firstType == secondType)
                {
                    return(typeByRef ? 1 : -1);
                }
            }
            if (typeByRef)
            {
                type = type.GetElementType();
            }
            bool firstImplicitFromType = true;

            if (isExplicit)
            {
                // 可以从 type 隐式转换的类型会更匹配,仅当允许显式类型转换时才需要检测。
                firstImplicitFromType = firstType.IsImplicitFrom(type);
                if (firstImplicitFromType != secondType.IsImplicitFrom(type))
                {
                    return(firstImplicitFromType ? -1 : 1);
                }
            }
            ConversionType convType = TypeExt.GetStandardConversion(firstType, secondType);

            if (convType == ConversionType.None)
            {
                if (firstType.IsSigned())
                {
                    if (secondType.IsUnsigned())
                    {
                        return(-1);
                    }
                }
                else if (firstType.IsUnsigned() && secondType.IsSigned())
                {
                    return(1);
                }
                return(0);
            }
            if (convType.IsExplicit() == firstImplicitFromType)
            {
                // secondType 可以隐式转换为 firstType。
                return(1);
            }
            // firstType 可以隐式转换为 secondType。
            return(-1);
        }