zoukankan      html  css  js  c++  java
  • 使用反射、特性简化代码

    假设现在有一个学生类(Student)

        
    /// <summary> /// 学生类 /// </summary> public class Student { /// <summary> /// 名字 /// </summary> private string name; public string Name { get { return name; } set { name = value; } } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 地址 /// </summary> public string Address { get; set; } /// <summary> /// 性别 /// </summary> public string Sex; }

    如果需要判断某些字段(属性)是否为空,是否大于0,便有以下代码:

    public static string ValidateStudent(Student student)
            {
                StringBuilder validateMessage = new StringBuilder();
                if (string.IsNullOrEmpty(student.Name))
                {
                    validateMessage.Append("名字不能为空");
                }
    
                if (string.IsNullOrEmpty(student.Sex))
                {
                    validateMessage.Append("性别不能为空");
                }
    
                if (student.Age <= 0)
                {
                    validateMessage.Append("年龄必填大于0");
                }
    
                //...... 几百行
    
                // 写到这里发现不对啊,如果必填项有20多个,难道我要一直这样写吗!
                return validateMessage.ToString();
            }

    这样的代码,重用性不高,而且效率低。

    我们可以用特性,反射,然后遍历属性并检查特性。

    首先自定义一个【必填】特性类,继承自Attribute

        /// <summary>
        /// 【必填】特性,继承自Attribute
        /// </summary>
        public sealed class RequireAttribute : Attribute
        {
            private bool isRequire;
            public bool IsRequire
            {
                get { return isRequire; }
            }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="isRequire"></param>
            public RequireAttribute(bool isRequire)
            {
                this.isRequire = isRequire;
            }
        }

    然后用这个自定义的特性标记学生类的成员属性:

    /// <summary>
        /// 学生类
        /// </summary>
        public class Student
        {   
            /// <summary>
            /// 名字
            /// </summary>
            private string name;
            [Require(true)]
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
    
            /// <summary>
            /// 年龄
            /// </summary>
            [Require(true)]
            public int Age { get; set; }
    
            /// <summary>
            /// 地址
            /// </summary>
            [Require(false)]
            public string Address { get; set; }
    
            /// <summary>
            /// 性别
            /// </summary>
            [Require(true)] 
            public string Sex;
        }

    通过特性检查类的属性:

      /// <summary>
            /// 检查方法,支持泛型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="instance"></param>
            /// <returns></returns>
            public static string CheckRequire<T>(T instance)
            {
                var validateMsg = new StringBuilder();
    
                //获取T类的属性
                Type t = typeof (T);
                var propertyInfos = t.GetProperties();
    
                //遍历属性
                foreach (var propertyInfo in propertyInfos)
                {
                    //检查属性是否标记了特性
                    RequireAttribute attribute = (RequireAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof (RequireAttribute));
    
                    //没标记,直接跳过
                    if (attribute == null)
                    {
                        continue;
                    }
    
                    //获取属性的数据类型
                    var type = propertyInfo.PropertyType.ToString().ToLower();
    
                    //获取该属性的值
                    var value = propertyInfo.GetValue(instance);
    
                    if (type.Contains("system.string"))
                    {
                        if (string.IsNullOrEmpty((string) value) && attribute.IsRequire)
                            validateMsg.Append(propertyInfo.Name).Append("不能为空").Append(",");
                    }
                    else if (type.Contains("system.int"))
                    {
                        if ((int) value == 0 && attribute.IsRequire)
                            validateMsg.Append(propertyInfo.Name).Append("必须大于0").Append(",");
                    }
                }
    
                return validateMsg.ToString();
            }

    执行验证:

    static void Main(string[] args)
            {
                var obj = new Student()
                {
                    Name = ""
                };
                Console.WriteLine(CheckRequire(obj));
                Console.Read();
            }

    结果输出:

    有人会发现,Sex也标记了[Require(true)],为什么没有验证信息,这是因为,Sex没有实现属性{ get; set; },GetProperties是获取不到的

    在上一篇文章中收藏了几个很有趣的网站,小伙伴们可以去看看哦。。。。。。。

  • 相关阅读:
    ROS和H3C,华为的端口汇聚方式
    wifi6 802.11ax技术标准 值得期待但无需等待!
    免信用卡更改Apple ID地区
    pip install失败报错解决方案
    黑产-起底身份倒卖产业:那些被公开叫卖的人生
    黄金
    jupyter nootbook本地使用指南
    current account(经常账户)
    outlier异常值检验原理和处理方法
    随机逻辑回归random logistic regression-特征筛选
  • 原文地址:https://www.cnblogs.com/ldyblogs/p/reflect.html
Copyright © 2011-2022 走看看