Esempio n. 1
0
        /// <summary>
        /// 基于指定的判据,从给定的字段集中选择一个字段。
        /// </summary>
        /// <param name="bindingAttr"><see cref="System.Reflection.BindingFlags"/> 值的按位组合。</param>
        /// <param name="match">用于匹配的候选字段集。</param>
        /// <param name="value">用于定位匹配字段的字段值。</param>
        /// <param name="culture">一个 <see cref="System.Globalization.CultureInfo"/> 实例,
        /// 用于在强制类型的联编程序实现中控制数据类型强制。</param>
        /// <returns>匹配的字段。</returns>
        public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value,
                                              CultureInfo culture)
        {
            int  idx       = 0;
            Type valueType = null;

            if (value != null)
            {
                valueType = value.GetType();
            }
            bool setField = (bindingAttr & BindingFlags.SetField) != 0;

            if (setField)
            {
                // 在设置 SetField 标志时,根据 value 的类型进行选择。
                for (int i = 0; i < match.Length; i++)
                {
                    if (CanChangeType(match[i].FieldType, valueType))
                    {
                        match[idx++] = match[i];
                    }
                }
                if (idx == 0)
                {
                    // 没有可匹配的字段。
                    return(null);
                }
                else if (idx > 1 && valueType != null)
                {
                    // 多个可匹配字段,尝试寻找类型匹配的最好的字段。
                    int len = idx;
                    idx = 1;
                    for (int i = 1; i < len; i++)
                    {
                        // 尝试进一步匹配字段类型。
                        int cmp = FindMostSpecificType(match[0].FieldType, match[i].FieldType, valueType);
                        if (cmp == 0)
                        {
                            match[idx++] = match[i];
                        }
                        else if (cmp == 2)
                        {
                            match[0] = match[i];
                            idx      = 1;
                        }
                    }
                }
            }
            else
            {
                idx = match.Length;
            }
            // 多个可匹配字段,寻找定义深度最深的字段。
            int  min   = 0;
            bool ambig = false;

            for (int i = 1; i < idx; i++)
            {
                // 比较定义的层级深度。
                int cmp = CompareHierarchyDepth(match[min], match[i]);
                if (cmp == 0)
                {
                    ambig = true;
                }
                else if (cmp == 2)
                {
                    min   = i;
                    ambig = false;
                }
            }
            if (ambig)
            {
                throw ExceptionHelper.AmbiguousMatchField();
            }
            return(match[min]);
        }