Example #1
0
 /// <summary>
 /// 查找最精确的输入类型和类型转换方法。
 /// </summary>
 /// <param name="method">类型转换方法。</param>
 /// <param name="inputRelation">实际输入类型到方法输入类型间的关系。</param>
 /// <param name="outputRelation">实际输出类型到方法输出类型间的关系。</param>
 private void GetBestConversion(UserConversionMethod method, TypeRelation inputRelation, TypeRelation outputRelation)
 {
     Contract.Requires(method != null);
     // 更新最优输入和输出类型。
     UpdateBestType(method.InputType, inputRelation, true, ref bestInputType, ref bestInputRelation);
     UpdateBestType(method.OutputType, outputRelation, false, ref bestOutputType, ref bestOutputRelation);
     if (method.InputType == bestInputType && method.OutputType == bestOutputType)
     {
         bestMethod.Value = method;
     }
 }
Example #2
0
        /// <summary>
        /// 在 <paramref name="basicType"/> 类型中寻找能够将对象从 <paramref name="inputType"/> 类型转换为
        /// <paramref name="basicType"/> 类型的用户自定义类型转换方法。
        /// 需要保证 <paramref name="basicType"/> 中存在用户自定义类型转换方法。
        /// </summary>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="basicType">要寻找自定义类型转换方法的类型。</param>
        /// <returns>将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="basicType"/>
        /// 类型的用户自定义类型转换方法。如果不存在则为 <c>null</c>。</returns>
        public static MethodInfo GetConversionFrom(Type basicType, Type inputType)
        {
            Contract.Requires(inputType != null && basicType != null);
            UserConversions convs = GetUserConversions(basicType);

            for (int i = 0; i < convs.ConvertToIndex; i++)
            {
                UserConversionMethod method = convs.Methods[i];
                if (method.InputType == inputType)
                {
                    return(method.Method);
                }
            }
            return(null);
        }
Example #3
0
        /// <summary>
        /// 在 <paramref name="basicType"/> 类型中寻找能够将对象从 <paramref name="basicType"/> 类型转换为
        /// <paramref name="outputType"/> 类型的用户自定义类型转换方法。
        /// 需要保证 <paramref name="basicType"/> 中存在用户自定义类型转换方法。
        /// </summary>
        /// <param name="basicType">要寻找自定义类型转换方法的类型。</param>
        /// <param name="outputType">要转换到的对象的类型。</param>
        /// <returns>将对象从 <paramref name="basicType"/> 类型转换为 <paramref name="outputType"/>
        /// 类型的用户自定义类型转换方法。如果不存在则为 <c>null</c>。</returns>
        public static MethodInfo GetConversionTo(Type basicType, Type outputType)
        {
            Contract.Requires(outputType != null && basicType != null);
            UserConversions convs = GetUserConversions(basicType);

            Contract.Assume(convs.ConvertToIndex >= 0);
            for (int i = convs.ConvertToIndex; i < convs.Methods.Length; i++)
            {
                UserConversionMethod method = convs.Methods[i];
                if (method.OutputType == outputType)
                {
                    return(method.Method);
                }
            }
            return(null);
        }
Example #4
0
            /// <summary>
            /// 查找合适的用户自定义类型转换方法。
            /// </summary>
            /// <returns>合适的用户自定义类型转换方法,如果不存在则为 <c>null</c>。</returns>
            public MethodInfo FindConversion()
            {
                UserConversions convs = GetUserConversions(inputType);

                if (convs != null)
                {
                    Contract.Assume(convs.ConvertToIndex >= 0);
                    for (int i = convs.ConvertToIndex; i < convs.Methods.Length; i++)
                    {
                        UserConversionMethod method = convs.Methods[i];
                        ConversionType       ctype  = ConversionFactory.GetStandardConversion(outputType, method.OutputType);
                        if (ctype == ConversionType.None)
                        {
                            continue;
                        }
                        TypeRelation inputRelation = (method.InputType == inputType) ?
                                                     TypeRelation.Best : TypeRelation.Second;
                        TypeRelation outputRelation = TypeRelation.Best;
                        if (ctype >= ConversionType.ExplicitNumeric)
                        {
                            outputRelation = TypeRelation.Second;
                        }
                        else if (ctype > ConversionType.Identity)
                        {
                            outputRelation = TypeRelation.Thirt;
                        }
                        GetBestConversion(method, inputRelation, outputRelation);
                    }
                }
                convs = GetUserConversions(outputType);
                if (convs != null)
                {
                    for (int i = 0; i < convs.ConvertToIndex; i++)
                    {
                        UserConversionMethod method = convs.Methods[i];
                        ConversionType       ctype  = ConversionFactory.GetStandardConversion(method.InputType, inputType);
                        if (ctype == ConversionType.None)
                        {
                            continue;
                        }
                        TypeRelation outputRelation = (method.OutputType == outputType) ?
                                                      TypeRelation.Best : TypeRelation.Second;
                        TypeRelation inputRelation = TypeRelation.Best;
                        if (ctype >= ConversionType.ExplicitNumeric)
                        {
                            inputRelation = TypeRelation.Second;
                        }
                        else if (ctype > ConversionType.Identity)
                        {
                            inputRelation = TypeRelation.Thirt;
                        }
                        GetBestConversion(method, inputRelation, outputRelation);
                    }
                }
                if (bestMethod.IsUnique)
                {
                    return(bestMethod.Value.Method);
                }
                if (bestMethod.IsAmbig)
                {
                    throw CommonExceptions.AmbiguousUserDefinedConverter(inputType, outputType);
                }
                return(null);
            }
Example #5
0
 /// <summary>
 /// 使用指定的类型转换方法列表和索引初始化 <see cref="UserConversions"/> 类的新实例。
 /// </summary>
 /// <param name="methods">类型转换方法列表。</param>
 /// <param name="index">转换到方法在列表中的起始索引。</param>
 public UserConversions(UserConversionMethod[] methods, int index)
 {
     Contract.Requires(methods != null && index >= 0 && index < methods.Length);
     this.Methods = methods;
     this.ConvertToIndex = index;
 }
Example #6
0
 /// <summary>
 /// 查找最精确的输入类型和类型转换方法。
 /// </summary>
 /// <param name="method">类型转换方法。</param>
 /// <param name="inputRelation">实际输入类型到方法输入类型间的关系。</param>
 /// <param name="outputRelation">实际输出类型到方法输出类型间的关系。</param>
 private void GetBestConversion(UserConversionMethod method, TypeRelation inputRelation, TypeRelation outputRelation)
 {
     Contract.Requires(method != null);
     // 更新最优输入和输出类型。
     UpdateBestType(method.InputType, inputRelation, true, ref bestInputType, ref bestInputRelation);
     UpdateBestType(method.OutputType, outputRelation, false, ref bestOutputType, ref bestOutputRelation);
     if (method.InputType == bestInputType && method.OutputType == bestOutputType)
     {
         bestMethod.Value = method;
     }
 }