Exemple #1
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)
        {
            ExceptionHelper.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 ExceptionHelper.AmbiguousMatchProperty();
            }
            return(match[min]);
        }