예제 #1
0
        /// <summary>
        /// 基于参数类型,从给定的方法集中选择一个方法。
        /// 允许通过指定 <see cref="BindingFlags.OptionalParamBinding"/> 来匹配可选参数。
        /// </summary>
        /// <param name="bindingAttr"><see cref="System.Reflection.BindingFlags"/> 值的按位组合。</param>
        /// <param name="infos">用于匹配的候选方法信息集。</param>
        /// <param name="len">方法信息集合的长度。</param>
        /// <param name="types">用于定位匹配方法的参数类型。</param>
        /// <returns>如果找到,则为匹配的方法信息;否则为 <c>null</c>。</returns>
        private MatchInfo SelectMethod(BindingFlags bindingAttr, MatchInfo[] infos, int len, Type[] types)
        {
            bool optionalParamBinding = (bindingAttr & BindingFlags.OptionalParamBinding) != 0;
            int  idx = 0;

            for (int i = 0; i < len; i++)
            {
                MatchInfo info = infos[i];
                Type      paramArrayType;
                if (MethodExt.CheckParameterCount(info.Parameters, types, info.ParamOrder,
                                                  optionalParamBinding, out paramArrayType))
                {
                    info.ParamArrayType = paramArrayType;
                    if (MakeGenericMethod(info, types) && CheckParameterType(info, types, optionalParamBinding))
                    {
                        infos[idx++] = info;
                    }
                }
            }
            if (idx == 0)
            {
                // 没有可匹配的方法。
                return(null);
            }
            else if (idx == 1)
            {
                // 只有一个可匹配的方法。
                return(infos[0]);
            }
            // 多个可匹配方法,寻找匹配的最好的方法。
            int  min   = 0;
            bool ambig = false;

            for (int i = 1; i < idx; i++)
            {
                int cmp = FindMostSpecificMethod(infos[min], infos[i], types);
                if (cmp == 0)
                {
                    ambig = true;
                }
                else if (cmp == 2)
                {
                    min   = i;
                    ambig = false;
                }
            }
            if (ambig)
            {
                throw CommonExceptions.AmbiguousMatchMethod();
            }
            return(infos[min]);
        }