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