Exemplo n.º 1
0
        /// <summary>
        /// 基于参数类型,从给定的属性集中选择一个属性。
        /// </summary>
        /// <param name="bindingAttr"><see cref="BindingFlags"/> 值的按位组合。</param>
        /// <param name="match">用于匹配的候选属性集。</param>
        /// <param name="returnType">匹配属性必须具有的返回值。</param>
        /// <param name="indexes">所搜索的属性的索引类型。</param>
        /// <param name="modifiers">使绑定能够处理在其中修改了类型的参数签名的参数修饰符数组。</param>
        /// <returns>如果找到,则为匹配的属性;否则为 <c>null</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="match"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="returnType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="match"/> 为空数组。</exception>
        /// <exception cref="ArgumentException"><paramref name="match"/> 中包含为 <c>null</c> 的元素。</exception>
        /// <exception cref="AmbiguousMatchException"><paramref name="match"/> 包含多个与 <paramref name="returnType"/>
        /// 匹配程度相同的方法。</exception>
        public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match,
                                                    Type returnType, Type[] indexes, ParameterModifier[] modifiers)
        {
            CommonExceptions.CheckArgumentNull(match, "match");
            Contract.EndContractBlock();
            // 按返回值筛选。
            int length = match.Length;

            if (returnType != null)
            {
                int len = 0;
                for (int i = 0; i < length; i++)
                {
                    if (CanChangeType(returnType, match[i].PropertyType))
                    {
                        match[len++] = match[i];
                    }
                }
                length = len;
            }
            // 按索引参数筛选。
            if (indexes != null)
            {
                int idxLen = indexes.Length;
                int len    = 0;
                for (int i = 0; i < length; i++)
                {
                    ParameterInfo[] parameters = match[i].GetIndexParameters();
                    if (parameters.Length == idxLen && (idxLen == 0 || CheckParameters(parameters, indexes)))
                    {
                        match[len++] = match[i];
                    }
                }
                length = len;
            }
            if (length == 0)
            {
                return(null);
            }
            if (length == 1)
            {
                return(match[0]);
            }
            // 多个可匹配属性,寻找类型最匹配的属性。
            length = FilterMember(match, length, (firstProperty, secondProperty) =>
                                  CompareProperty(firstProperty, secondProperty, returnType, indexes));
            PropertyInfo best = GetDeepestMember(match, length);

            if (best == null)
            {
                throw CommonExceptions.AmbiguousMatchProperty();
            }
            return(best);
        }
Exemplo 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]);
        }