/// <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; } }
/// <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); }
/// <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); }
/// <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); }
/// <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; }