exercise: 反射获取指定的属性值 --CSharp

 

    /// <summary>
    /// 放到 public static 非索引 property上
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = true)]
    class CheckedPropertyAttribute: Attribute
    {

        /// <summary>
        /// 必要的访问修饰
        /// </summary>
        private const BindingFlags REQUIRED_BINDING_FLAGS = BindingFlags.Public
            | BindingFlags.Static | BindingFlags.GetProperty;


        /// <summary>
        /// 被标记的别名
        /// </summary>
        public string AliasName { get; set; }

        /// <summary>
        /// 进行排序, 在有顺序要求的地方设置该属性
        /// </summary>
        public int Order { get; set; } = 0;


        public CheckedPropertyAttribute() : this(string.Empty)
        {
        }

        public CheckedPropertyAttribute(string aliasName)
        {
            this.AliasName = aliasName;
        }

        
        /// <summary>
        /// 带有 CheckedProperty 的属性, 如果没有任何匹配的属性, 则返回数组长度为 0
        /// </summary>
        /// <typeparam name="T">被搜索属性的类型</typeparam>
        /// <param name="holderType">包含 被搜索属性的 类型</param>
        /// <returns>item1 = propertyName, item2 = aliasName, item3 = propertyValue </returns>
        public static Tuple<string, string, T>[] CollectChecked<T>(Type holderType)
        {
            return holderType.GetProperties(REQUIRED_BINDING_FLAGS)
                .Select(ExtractInfos)
                .Where((t) => t != null)
                .OrderBy((t) => t.Item2.Order)
                .Select((t) => new Tuple<string, string, T>(t.Item1, t.Item2.AliasName, t.Item3))
                .ToArray();

            // local functions
            Tuple<string, CheckedPropertyAttribute, T> ExtractInfos(PropertyInfo pi)
            {
                if (IsIndexParameter(pi)
                    || !TryGetPropertyValue(pi, out T propVal)
                    || !TryGetAttr(pi, out CheckedPropertyAttribute cpa))
                {
                    return null;
                }

                return new Tuple<string, CheckedPropertyAttribute, T>(pi.Name, cpa, propVal);
            }

            bool IsIndexParameter(PropertyInfo pi)
            {
                var paramInfos = pi.GetIndexParameters();
                return (paramInfos.Length != 0);
            }

            bool TryGetPropertyValue(PropertyInfo pi, out T propVal)
            {
                object pVal = pi.GetValue(null, null);
                bool valGetted = typeof(T).IsAssignableFrom(pi.PropertyType);

                propVal = valGetted ? (T)pVal : default(T);
                return valGetted;
            }

            bool TryGetAttr(PropertyInfo pi, out CheckedPropertyAttribute attr)
            {
                attr = (CheckedPropertyAttribute)GetCustomAttribute(
                    pi, typeof(CheckedPropertyAttribute), true);
                return (attr != null);
            }
        }



    } // class

 

 

 

 

 

--- THE END ---

 

posted @ 2021-01-23 15:17  太初谷神  阅读(109)  评论(0编辑  收藏  举报