Esempio n. 1
0
 /// <summary>
 /// 添加将对象从 <typeparamref name="TInput"/> 类型转换为 <typeparamref name="TOutput"/> 类型的转换器。
 /// </summary>
 /// <typeparam name="TInput">输入对象的类型。</typeparam>
 /// <typeparam name="TOutput">输出对象的类型。</typeparam>
 /// <param name="converter">将对象从 <typeparamref name="TInput"/> 类型转换为
 /// <typeparamref name="TOutput"/> 类型的转换器。</param>
 /// <exception cref="ArgumentNullException"><paramref name="converter"/> 为 <c>null</c>。</exception>
 /// <remarks><paramref name="converter"/> 不会覆盖预定义的隐式、显式类型转换和用户自定义的类型转换。
 /// 对于相同输入/输出类型的 <paramref name="converter"/>,后设置的会覆盖先设置的,以及任何
 /// <see cref="IConverterProvider"/> 提供的类型转换方法。</remarks>
 public static void AddConverter <TInput, TOutput>(Converter <TInput, TOutput> converter)
 {
     CommonExceptions.CheckArgumentNull(converter, "converter");
     Contract.EndContractBlock();
     ConversionFactory.AddConverterProvider(new ConverterProvider(converter, typeof(TInput), typeof(TOutput)));
 }
Esempio n. 2
0
        /// <summary>
        /// 基于指定的判据,从给定的属性集中选择一个属性。
        /// </summary>
        /// <param name="bindingAttr"><see cref="System.Reflection.BindingFlags"/> 值的按位组合。</param>
        /// <param name="match">用于匹配的候选属性集。</param>
        /// <param name="returnType">匹配属性必须具有的返回值。</param>
        /// <param name="indexes">所搜索的属性的索引类型。</param>
        /// <param name="modifiers">使绑定能够处理在其中修改了类型的参数签名的参数修饰符数组。</param>
        /// <returns>如果找到,则为匹配的属性;否则为 <c>null</c>。</returns>
        public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType,
                                                    Type[] indexes, ParameterModifier[] modifiers)
        {
            CommonExceptions.CheckArgumentNull(match, "match");
            if (match.Length == 0)
            {
                return(null);
            }
            int idxLen = indexes == null ? 0 : indexes.Length;

            // 构造属性信息数组。
            MatchInfo[] infos = new MatchInfo[match.Length];
            int         idx   = 0;

            for (int i = 0; i < match.Length; i++)
            {
                if (match[i] != null)
                {
                    ParameterInfo[] parameters = match[i].GetIndexParameters();
                    // 匹配属性类型与索引参数。
                    if (parameters.Length == idxLen && CheckParameters(infos[i], indexes, idxLen) &&
                        CanChangeType(match[i].PropertyType, returnType))
                    {
                        infos[idx] = new MatchInfo(parameters, MethodExt.GetParamOrder(idxLen));
                        match[idx] = match[i];
                        idx++;
                    }
                }
            }
            if (idx == 0)
            {
                return(null);
            }
            if (idx == 1)
            {
                return(match[0]);
            }
            // 多个可匹配属性,寻找匹配的最好的属性。
            int  min   = 0;
            bool ambig = false;

            for (int i = 1; i < idx; i++)
            {
                // 先比较属性类型。
                int cmp = FindMostSpecificType(match[min].PropertyType, match[i].PropertyType, returnType);
                if (cmp == 0 && indexes != null)
                {
                    // 再比较属性参数。
                    cmp = FindMostSpecific(infos[min], infos[i], indexes);
                }
                if (cmp == 0)
                {
                    // 最后比较定义的层级深度。
                    cmp = CompareHierarchyDepth(match[min], match[i]);
                    if (cmp == 0)
                    {
                        ambig = true;
                    }
                }
                if (cmp == 2)
                {
                    ambig = false;
                    min   = i;
                }
            }
            if (ambig)
            {
                throw CommonExceptions.AmbiguousMatchProperty();
            }
            return(match[min]);
        }